Reflection.Net:如何加载依赖项?

34

我试图使用反射为我的Windows .Net应用程序添加一个插件系统,但当存在具有依赖关系的插件时,它会失败。

插件类必须实现一个名为'IAddon'的接口,并且必须有一个空构造函数。
主程序使用反射加载插件:

Assembly assembly = Assembly.LoadFile(@"C:\Temp\TestAddon\Addon.dll");
Type t = assembly.GetType("Test.MyAddon");
ConstructorInfo ctor = t.GetConstructor(new Type[] { });
IAddon addon= (IAddon) ctor.Invoke(new object[] { });
addon.StartAddon();

当插件不使用依赖项时,它的效果很好。 但是,如果我的插件引用并使用另一个DLL(C:\ Temp \ TestAddon \ MyTools.dll),该DLL保存在与插件相邻的磁盘上,则会失败:
System.IO.FileNotFoundException: 无法加载文件或程序集'MyTools.dll'或其某个依赖项。

我不想将插件的DLL复制到我的可执行文件旁边,我该如何告诉.Net运行时在“C:\ Temp \ TestAddon \”中搜索所有依赖项?

请注意添加

Assembly assembly = Assembly.LoadFile(@"C:\Temp\TestAddon\MyTools.dll");

请勿更改任何内容。

5个回答

52
如果MyTools.dllAddon.dll位于同一目录中,则你只需要调用Assembly.LoadFrom而不是Assembly.LoadFile来使你的代码工作。否则,处理AppDomain.AssemblyResolve事件是正确的方法。

很遗憾@Andreas自2010年以来就没有出现了,如果我认为你会在意的话,我会给你一个赏金。飞吧,你这个小奥地利天才。 - Liam

1

有几个选项:

  1. 您可以附加到 AppDomain.AssemblyResolve 来帮助 CLR 解析程序集。
  2. 您可以考虑将插件隔离到它们自己的 AppDomain 中(请参阅 System.AddIn 命名空间和 this website)。

1

你有考虑过使用控制反转容器吗?我使用Castle Windsor和一个外部的Boo文件,让我可以轻松地扩展应用程序,而无需重新编译或担心提供依赖项。


1

您可以使用反射方式访问私有的Assembly._GetReferencedAssemblies()

虽然该方法在将来的 .NET 框架版本中可能会发生变化,但这似乎不太可能发生——ASP.NET 严重依赖它,尽管他们可能会将其从mscorlib移动到System.Web,这是我所知道的唯一引用该方法的程序集。


1

Assembly.LoadFrom在我尝试在我的插件中使用webService时工作得很好,但是我遇到了一个"无法将类型为'X'的对象强制转换为类型'X'"的异常。

虽然不太美观,但我会使用AppDomain.AssemblyResolve和Assembly.LoadFile。

谢谢大家。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接