c#:如何在动态加载的程序集中更改动态加载程序集的依赖项的搜索目录

本文关键字:程序集 加载 动态 依赖 搜索 程序 集中 | 更新日期: 2023-09-27 18:17:13

这很复杂,但这里是:

为了与另一个应用程序集成(在单独的目录中),我们动态加载它的一个程序集,然后使用Activator从该程序集实例化对象。目标程序集加载得很好,但是当创建对象的实例时,它试图动态加载一些额外的依赖项并失败,因为它在我们的应用程序目录:

中找到了它们的新版本。
var assm = Assembly.LoadFrom("full.path.to.asm"));
var objType = assm.GetType("MyType", true);
var obj = Activator.CreateInstance(objType);

assm负载精细,得到objType。异常发生激活obj,因为它依赖于一个旧版本的程序集(它确实在其目录中),但它首先在我们的应用程序目录中找到一个较新的程序集,并抱怨它是错误的签名。

我尝试设置环境。

c#:如何在动态加载的程序集中更改动态加载程序集的依赖项的搜索目录

您需要订阅AppDomain.AssemblyResolve事件。在那里,您可以重定向它以检查另一个目录中缺少的程序集。

public static object CreateInstance()
{    
    AppDomain currentDomain = AppDomain.CurrentDomain;
    currentDomain.AssemblyResolve += MyResolveEventHandler;
    var assm = Assembly.LoadFrom("full.path.to.asm"));
    var objType = assm.GetType("MyType", true);
    var obj = Activator.CreateInstance(objType);
}
private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
{
    if (args.Name == "SomeAssemblyIntheOtherFolder")
    {
        var path = Path.Combine(Path.GetDirectoryName("full.path.to.asm"), "SomeAssemblyIntheOtherFolder.dll");
        return Assembly.LoadFrom(path);
    }
    return null;
}

Update:第二个选项是在你的应用程序中添加一个程序集绑定重定向,这使得其他应用程序使用你拥有的新版本的dll,而不是他们编译的版本。

下面是一个使用库Common.Logging.dll完成的示例,您将把它放在app.config文件中。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  ...
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
            <assemblyIdentity name="Common.Logging" publicKeyToken="af08829b84f0328e" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-3.2.0.0" newVersion="3.2.0.0" />
        </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

这将导致在你的程序中加载的任何程序集引用0.0.0.03.2.0.0之间的Common.Logging.dll库的任何版本,而不是使用3.2.0.0版本。