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

jay*_*ars 21 .net c# versioning visual-studio-2015

我已经获得了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
Run Code Online (Sandbox Code Playgroud)

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!");
}
Run Code Online (Sandbox Code Playgroud)

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

<!-- [Edited: see history for previous version] -->
<Reference Include="Common.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f3b12eb6de839f43, processorArchitecture=MSIL">
  <HintPath>libs\Common.Data.1_0_0_0.dll</HintPath>
  <Aliases>v10</Aliases>
</Reference>

<Reference Include="Common.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=f3b12eb6de839f43, processorArchitecture=MSIL">
  <HintPath>libs\Common.Data.2_0_0_0.dll</HintPath>
  <Aliases>v20</Aliases>
</Reference>

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="Common.Data" publicKeyToken="f3b12eb6de839f43" culture="neutral" />
      <codeBase version="1.0.0.0" href="libs\Common.Data.1_0_0_0.dll" />
      <codeBase version="2.0.0.0" href="libs\Common.Data.2_0_0_0.dll" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>
Run Code Online (Sandbox Code Playgroud)

我已经成功建立了.

但是,当我尝试运行它,我得到MissingMethodExceptionUserData.loadData.

错误

我经历过多个stackoverflow帖子,msdn和codeproject文章,但似乎无法让它工作.

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

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

[EDIT1]

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

[EDIT2]

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

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="Common.Data" 
                        publicKeyToken="f3b12eb6de839f43" 
                        culture="neutral" />
      <bindingRedirect oldVersion="1.0.0.0"
                       newVersion="2.0.0.0"/>
    </dependentAssembly>
  </assemblyBinding>
</runtime>
Run Code Online (Sandbox Code Playgroud)

但它仍然无效.我现在要了FileNotFoundException.

[EDIT3]

好吧,我几乎可以肯定这<bindingRedirect>是不对的,应该是<codeBase>.

我尝试从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

我尝试修改<Reference />为包含/排除<SpecificVersion>True</SpecificVersion>没有效果.

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

感觉就像我几乎得到了它,但并不完全.如何让Visual Studio正确构建?

[Edit4]

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

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

在此输入图像描述

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

在运行时,我得到了MissingMethodException.

我不知道是什么4- Find the and put in False意思,所以我尝试的所有组合<Private>,<SpecificVersion>以及设置<Reference Include>于FQNs,但没有这些组合的工作.

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

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

小智 10

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

<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  <dependentAssembly>
        <assemblyIdentity name="myAssembly"
                          publicKeyToken="here token dll"
                          culture="neutral" />
       <bindingRedirect oldVersion="0.0.0.0-1.0.0.0" newVersion="1.0.0.0" />
       <bindingRedirect oldVersion="1.0.0.1-2.0.0.0" newVersion="2.0.0.0" />
       <codeBase version="1.0.0.0" href="folder\namedll.dll" />
       <codeBase version="2.0.0.0" href="folder\namedll.dll" />
      </dependentAssembly>
   </assemblyBinding>
Run Code Online (Sandbox Code Playgroud)

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

1-卸载受影响的项目
2-右键单击项目
3-单击编辑项目
4-查找<AutoGenerateBindingRedirects>属性并将其设置为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("");
}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

18688 次

最近记录:

7 年,4 月 前