使用相同dll的2个不同版本?

我已经获得了2个预编译的dll:

Common.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f3b12eb6de839f43, processorArchitecture=MSIL Common.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=f3b12eb6de839f43, processorArchitecture=MSIL 

API差异示例:

API

我正在尝试将两者加载到一个项目中,以执行以下操作:

 extern alias v10; extern alias v20; private static void UpgradeUser() { // Load old user var userOld = new v10::Common.Data.UserData(); userOld.loadData("user.dat"); // Create new user var userNew = new v20::Common.Data.UserData(); // Copy properties userNew.FirstName = userOld._firstName; userNew.LastName = userOld._lastName; userNew.Age = userOld._age; // Invoke method from v10 and v20 API userOld.version(); userNew.DisplayVersion(); if (userNew.GetUserInfo() != userOld.getInfo()) { throw new Exception("Discrepencies in upgrade "); } Console.WriteLine("Upgrade done!"); } 

我已将项目引用和app.config设置为以下内容。 我也手动将dll复制到我的输出文件夹中,匹配appconfig hrefs

   libs\Common.Data.1_0_0_0.dll v10   libs\Common.Data.2_0_0_0.dll v20           

我已经成功地建立了。

但是当我尝试运行它时,我得到UserData.loadDataMissingMethodException

错误

我经历过多个stackoverflowpost,msdn和codeproject文章,但似乎无法让它工作。

链路1 , 链路2 , 链路3 , 链路4

认为我错过了一个重要的步骤,但无法弄清楚是什么,并且可以真正使用一些帮助。

[EDIT1]

我已经尝试过单独使用dll,它们可以工作。 (删除了混乱。查看截图的版本历史记录)

[EDIT2]

我尝试了Mukesh Kumar的提议,并将我的app.config更改为:

         

但它仍然无效。 我现在收到FileNotFoundException

[EDIT3]

好吧,我几乎可以肯定不正确,而应该是

我尝试从CLI编译:

csc Program.cs /reference:v10=libs/Common.Data.1_0_0_0.dll /reference:v20=libs/Common.Data.2_0_0_0.dll

它工作正常。 我能够同时使用这两个API:

在此处输入图像描述

但是当我尝试从Visual Studio构建它时,它会抱怨/引用,即使我已经指定了引用别名:

The extern alias 'v10' was not specified in a /reference option

我已经尝试修改以包含/排除True而不起作用。

我找到了这篇文章 ,解决方案是删除并重新添加路径。 使用该解决方案,Visual Studio构建正常,但我回到System.MissingMethodException

感觉就像我差不多了,但并不完全。 如何让Visual Studio正确构建?

[Edit4]

我尝试过米格尔的方法,但仍然无法正常工作。

在此尝试中,我已将dll重命名为其原始名称,并将其存储在不同的文件夹中。

在此处输入图像描述

然后我更新了app.config以执行bindingRedirect和codebase。

运行它时,我遇到了MissingMethodException

我不确定4- Find the and put in False是什么意思,所以我尝试了所有组合,以及将设置为FQN,但这些组合都不起作用。

看看我的第3次编辑,我成功地通过CLI完成编译并运行示例(使用我重命名的dlls + app.config codebase hrefs)。

我现在的问题是,如何配置我的csproj,所以它构建相同。

您需要将dependentAssembly与bindingRedirect一起使用,但您还需要将dll放在不同的文件夹中或使用其他名称保存。 完成此操作后,您需要在app.config中添加以下内容:

          

使用此代码应编译并运行,但有时VS在编译时删除或覆盖app.config中的代码。 你需要在编译文件夹的配置文件中检查它。 如果成功,您可以编辑.csproj。 为此你必须这样做:

1-卸载受影响的项目
2-右键单击项目
3-单击“编辑项目”
4-找到属性并将其设置为False
5-保存更改并重新加载项目

这对我有用。 在我的项目中,我使用的是两个版本的Automapper。

最后,另一种解决方案是使用AppDomain.CurrentDomain.AssemblyResolve构建事件并加载特定的dll。

为此,您需要捕获事件:

 AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); public static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { //debug and check the name if (args.Name == "MyDllName") return Assembly.LoadFrom("c:\\pathdll\midllv1.dll") else if(args.Name ="MyDllName2") return Assembly.LoadFrom("c:\\pathdll\midllv2.dll"); else return Assembly.LoadFrom(""); } 

尝试将您的配置详细信息如下所示。

      

在这里你可以为你提供旧版本和新版本。 你可以按照这篇文章和这个 。

希望这会帮助你。

缺少一个符合我需要的完整答案我决定用AssemblyResolve方式捐赠我的解决方案,使用两个dll并加载相关文件,使用reflection来解析类型。 对于这个演示,我创建了两个名为MathFuncs dll,尝试调用它们的Add.add函数将在两个不同的实现中解析。要查看不同的结果,请在值1和2之间切换版本整数:

 public static int version = 1; public static void Main(string[] args) { AppDomain.CurrentDomain.AssemblyResolve += Program.CurrentDomain_AssemblyResolve; version = 1; Type a = Type.GetType("MathFuncs.Add, MathFuncs, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); MethodInfo methodInfo = a?.GetMethod("add"); object result = null; if (methodInfo != null) { object[] parametersArray = new object[] {1, 2}; result = methodInfo.Invoke(Activator.CreateInstance(a, null), parametersArray); } if (result != null) { Console.WriteLine((int)result); } else { Console.WriteLine("failed"); } Console.Read(); } public static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { FileInfo fi = null; if (version == 1) { fi = new FileInfo("C:\\Users\\ohbitton\\Desktop\\MathFuncs\\MathFuncs.dll"); } else { fi = new FileInfo("C:\\Users\\ohbitton\\Desktop\\MathFuncs2\\MathFuncs.dll"); } return Assembly.LoadFrom(fi.FullName); } 

要获取Type.GetType的命名空间的完整名称,可以使用powershell:

 ([system.reflection.assembly]::loadfile("C:\Users\ohbitton\Desktop\MathFuncs\MathFuncs.dll")).FullName