Using 2 different versions of the same dll?

天涯浪子 提交于 2019-11-29 23:06:52
miguel

You need to use a dependentAssembly with bindingRedirect but also you need put dlls in different folder or save with a different name. With this done, you need to put the following in your 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>

With this code should compile and run, but sometimes VS deletes or overwrite the code in the app.config when compiles it. You need to check it in config file of compilation folder. If this succeeds, you can edit the .csproj. For this you must do:

1- Unload the project affected
2- Right click on project
3- Click Edit project
4- Find the <AutoGenerateBindingRedirects> property and set it to False
5- Save changes and reload project

This works for me. In my project, I'm using two versions of Automapper.

Finally, another solution is to use the AppDomain.CurrentDomain.AssemblyResolve build event and load the specific dll.

For that, you need catch the event:

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("");
}

Try to put your config details like as following.

 <dependentAssembly>
            <assemblyIdentity name="myAssembly"
                              publicKeyToken="32ab4ba45e0a69a1"
                              culture="neutral" />
            <bindingRedirect oldVersion="1.0.0.0"
                             newVersion="2.0.0.0"/>
  </dependentAssembly>

here you can provide you dll old version and new version. You can just follow this article and also this.

Hope this will help you.

Missing a complete answer which suits my needs i decided to donate my solution with the AssemblyResolve way to use two dlls and load the relevant from file, using reflection to resolve the type . For this demo i created two dlls called MathFuncs, trying to invoke their Add.add function will resolve in two different implementations.To see the different results switch the version integer between the values 1 and 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);

    }

To get the complete name of the namespace for the Type.GetType you can use powershell :

([system.reflection.assembly]::loadfile("C:\Users\ohbitton\Desktop\MathFuncs\MathFuncs.dll")).FullName
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!