C# 相同的DLL有两个不同的版本

C# 相同的DLL有两个不同的版本,c#,dll,nuget,C#,Dll,Nuget,我有两个不同的项目,都使用NuGet的Newtonsoft.Json 项目A使用9.0.1版 项目B使用11.0.1版 在构建项目时,一个dll将覆盖另一个dll,因为它们都在同一文件夹中编译 如何在单独的文件中重定向dll的编译,如何说项目A使用9.0.1,项目B使用11.0.1 如果有一个文件夹“Newtonsoft”就好了,有两个文件夹“11”和“9”。在这些文件夹中是特定的版本。(如果有另一个解决方案,那么我对另一个也没意见) 项目A和项目B都是“插件”,我的应用程序正在使用这些插件

我有两个不同的项目,都使用NuGet的Newtonsoft.Json

  • 项目A使用9.0.1版
  • 项目B使用11.0.1版
在构建项目时,一个dll将覆盖另一个dll,因为它们都在同一文件夹中编译

如何在单独的文件中重定向dll的编译,如何说项目A使用9.0.1,项目B使用11.0.1

如果有一个文件夹“Newtonsoft”就好了,有两个文件夹“11”和“9”。在这些文件夹中是特定的版本。(如果有另一个解决方案,那么我对另一个也没意见)

项目A和项目B都是“插件”,我的应用程序正在使用这些插件,其中包括插件文件夹中的插件。。这意味着我当前有一个使用以下dll的应用程序(它们都在一个文件夹中):

  • Project_A.dll
  • Project_B.dll
  • NewtonSoft.Json.dll(9.0.1或11.0.1)
ProjectA.dll

这是我的app.config

项目A:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="YamlDotNet" publicKeyToken="ec19458f3c15af5e" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

项目B:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
        <codeBase version="11.0.0.1" href="Newtonsoft.Json.dll" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /></startup></configuration>

您可以将部件放在不同的文件夹中(不一定直接放在bin文件夹中),并使用以下元素:



已解决

通过这样做使其工作:

在使用Newtonsfot.Json的任何方法/类之前,我使用以下两行代码:

//The AssemblyResolve event is called when the common language runtime tries to bind to the assembly and fails.
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(currentDomain_AssemblyResolve);
如果应用程序将引发异常,则始终会调用该事件

无法加载文件或程序集'Newtonsoft.Json,版本=9.0.0.1, 文化=中性,PublicKeyToken=30AD4FE6B2A6EED'或其 依赖关系。系统找不到指定的文件

因此,事件将捕获事件并加载正确的dll:

Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    //This handler is called only when the common language runtime tries to bind to the assembly and fails.

    //Retrieve the list of referenced assemblies in an array of AssemblyName.
    Assembly MyAssembly, objExecutingAssemblies;
    string strTempAssmbPath = "";

    objExecutingAssemblies = Assembly.GetExecutingAssembly();
    AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();

    //Loop through the array of referenced assembly names.
    foreach (AssemblyName strAssmbName in arrReferencedAssmbNames)
    {
        //Check for the assembly names that have raised the "AssemblyResolve" event.
        if (strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(",")) == args.Name.Substring(0, args.Name.IndexOf(",")))
        {
            //Build the path of the assembly from where it has to be loaded.
            //The following line is probably the only line of code in this method you may need to modify:
            strTempAssmbPath = "C:\\Program Files\\PATH TO YOUR FOLDER" + "\\Newtonsoft.Json\\9.0.1";
            if (!strTempAssmbPath.EndsWith("\\")) strTempAssmbPath += "\\";
            //strTempAssmbPath += args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
            strTempAssmbPath += strAssmbName.Name + ".dll";
            break;
        }

    }
    //Load the assembly from the specified path.
    MyAssembly = Assembly.LoadFrom(strTempAssmbPath);

    //Return the loaded assembly.
    return MyAssembly;
}

信用证:

您是否考虑过将两个项目更改为使用同一版本?@mjwills我有,但项目B使用了一些功能,这些功能仅在11.0.1中可用。在项目A中,我使用的是另一个Nuget包,它只适用于9.0.1。因此,我需要这两个dll,因为我无法升级/降级版本。bindingRedirect必须应用于使用这些dll的项目。因此,您的EXE项目,而不是库项目。答案属于答案,而不是编辑到问题中。如果您有答案,请将其作为一个发布,并(在冷却期后)接受它。我明天将尝试:)
Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    //This handler is called only when the common language runtime tries to bind to the assembly and fails.

    //Retrieve the list of referenced assemblies in an array of AssemblyName.
    Assembly MyAssembly, objExecutingAssemblies;
    string strTempAssmbPath = "";

    objExecutingAssemblies = Assembly.GetExecutingAssembly();
    AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();

    //Loop through the array of referenced assembly names.
    foreach (AssemblyName strAssmbName in arrReferencedAssmbNames)
    {
        //Check for the assembly names that have raised the "AssemblyResolve" event.
        if (strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(",")) == args.Name.Substring(0, args.Name.IndexOf(",")))
        {
            //Build the path of the assembly from where it has to be loaded.
            //The following line is probably the only line of code in this method you may need to modify:
            strTempAssmbPath = "C:\\Program Files\\PATH TO YOUR FOLDER" + "\\Newtonsoft.Json\\9.0.1";
            if (!strTempAssmbPath.EndsWith("\\")) strTempAssmbPath += "\\";
            //strTempAssmbPath += args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
            strTempAssmbPath += strAssmbName.Name + ".dll";
            break;
        }

    }
    //Load the assembly from the specified path.
    MyAssembly = Assembly.LoadFrom(strTempAssmbPath);

    //Return the loaded assembly.
    return MyAssembly;
}