这是令人费解的,但这里有:
为了与另一个应用程序(在一个单独的目录中)集成,我们动态加载其中一个程序集,然后使用Activator从该程序集中实例化一个对象。目标程序集加载正常,但是在创建对象的实例时,它会尝试动态加载一些额外的依赖项并失败,因为它在我们的app目录中找到了它们的更新版本:
var assm = Assembly.LoadFrom("full.path.to.asm"));
var objType = assm.GetType("MyType", true);
var obj = Activator.CreateInstance(objType);
assm
加载正常,并获得objType
。激活obj
时发生异常,因为它依赖于程序集的旧版本(它在目录中有它),但它首先在我们的app目录中找到一个更新的版本并抱怨它是错误的签名。
我首先尝试设置Environment.CurrentDirectory,但它没有任何区别。
答案 0 :(得分: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>
这将导致您的程序中加载的任何程序集在Common.Logging.dll
和0.0.0.0
之间引用任何版本的3.2.0.0
库,只使用3.2.0.0
而不是他们构建的版本。