30

我尝试使用反射向我的 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),它将失败:
System.IO.FileNotFoundException: 无法加载文件或程序集 'MyTools.dll ' 或其依赖项之一。

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

请注意,添加

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

不要改变任何东西。

4

5 回答 5

47

如果MyTools.dll与Addon.dll位于同一目录中,您需要做的就是调用Assembly.LoadFrom而不是Assembly.LoadFile让您的代码工作。否则,处理AppDomain.AssemblyResolve事件是要走的路。

于 2008-10-08T09:31:14.427 回答
1

几个选项:

  1. 您可以附加到AppDomain.AssemblyResolve以帮助 CLR 解析程序集。
  2. 您可以考虑将加载项隔离到它们自己的中AppDomain(请参阅System.AddIn命名空间和本网站)。
于 2008-10-08T09:10:02.600 回答
1

您是否考虑过使用控制反转容器?我将 Castle Windsor 与外部 Boo 文件一起使用,这让我可以轻松扩展应用程序,而无需重新编译或担心提供依赖项

于 2008-10-08T09:39:15.690 回答
1

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

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

于 2008-10-08T09:57:45.327 回答
1

在我尝试在插件中使用 webService 之前,Assembly.LoadFrom 运行良好,我遇到了“无法将 'X' 类型的对象转换为 'X' 类型”异常。

这很难看,但我会将 Assembly.LoadFile 与 AppDomain.AssemblyResolve 一起使用。

多谢你们。

于 2008-10-08T13:39:58.827 回答