【问题标题】:C#: How to change search directory for dependencies of dynamically loaded assemblies within a dynamically loaded assembly?C#:如何在动态加载的程序集中更改动态加载程序集的依赖项的搜索目录?
【发布时间】:2016-11-09 17:42:55
【问题描述】:

这很复杂,但这里是:

为了与另一个应用程序集成(在单独的目录中),我们动态加载其中一个程序集,然后使用 Activator 从该程序集中实例化一个对象。目标程序集加载正常,但是在创建对象实例时,它会尝试动态加载一些额外的依赖项并失败,因为它在我们的应用程序目录中找到了它们的更新版本:

var assm = Assembly.LoadFrom("full.path.to.asm"));
var objType = assm.GetType("MyType", true);
var obj = Activator.CreateInstance(objType);

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

我尝试先设置 Environment.CurrentDirectory,但没有任何区别。

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    您需要订阅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;
    
    }
    

    更新:第二个选项是在您的应用程序中添加程序集绑定重定向,这使得其他应用程序使用您拥有的较新版本的 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 而不是它们构建时使用的版本.

    【讨论】:

    • 了解了有关 AssemblyResolve 事件的新知识,谢谢!
    猜你喜欢
    • 2014-05-14
    • 1970-01-01
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 2014-07-08
    • 2011-10-12
    • 1970-01-01
    • 2013-03-07
    相关资源
    最近更新 更多