我正在项目中使用两个支持DLL的应用程序。ClassLibrary1.dll
和ClassLibrary2.dll
。ClassLibrary2.dll是可选的,仅由ClassLibrary1.dll
使用。应用程序具有显式导入DLL的功能。如果我将两个DLL导入应用程序,则一切正常。
当我不导入可选的ClassLibrary2.dll时,问题就出现了。
在应用程序启动时,我检查程序集是否存在:
var assemblyName = "ClassLibrary2.dll, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
var assembly = (from a in assemblies
where a.FullName == assemblyName
select a).SingleOrDefault();
// this IsClassLibrary2Exists property become true when the DLL exists
if (assembly != null)
{
Props.IsClassLibrary2Exists = true;
}
下面是我如何在ClassLibrary1中调用ClassLibrary2方法
if(Props.IsClassLibrary2Exists){
ClassLibrary2.SpecialProduct.GetSpecialProduct(Id);
}
程序集不存在时出现错误:
“系统.IO.文件未找到异常:“未能加载文件或程序集”ClassLibrary2,版本=1.0.0.0,区域性=中性,PublicKeyToken=null“或它的某个依赖项。系统找不到指定的文件。”“
2条答案
按热度按时间b1payxdu1#
我同意Dai的评论,即根本问题是
ClassLibrary1
对ClassLibrary2
有一个硬编码的依赖关系,因此问题福尔斯在如何将其解耦上。一种对我有效的方法是建立一个
Interface
类库,它只包含应用程序可能尝试使用的插件接口(但同时可能没有附加示例),插件服务器和客户端都可以引用它。Interface
类库类库1
SpecialProduct
成员与ClassLibrary2
解耦,因为它是接口而不是类。类库2
测试(使用控制台应用程序进行概念验证)
可用的插件位于应用程序运行目录的
Plugins
子文件夹中。ClassLibrary2
最初未被引用或加载。rmbxnbpk2#
要成功阻止一个程序集请求另一个程序集,您需要通过未执行的 * 方法 * 完成对“程序集2”的所有访问。使用
if
保护访问是不够的,因为整个方法需要首先进行JIT,这需要加载另一个程序集。什么 * 可能 * 会起作用:
请注意,以一种很难/不可能在运行时修复的方式使用“另一个库”是非常容易的-静态属性/构造函数可以在任何时候调用,因此从另一个库引用任何东西都会失败,从另一个库引用字段/属性/方法参数/返回使用类型甚至通过反射都会失败......以及许多其他情况。
如果可能的话,最好动态加载程序集并让它实现共享接口,这样您就可以将反射限制在示例化部分,但要通过强类型接口使用这些类。