我们有一个相当大的 C# 代码库,该产品已被分成许多程序集,以避免单一的产品并强制执行一些代码质量标准(客户特定的功能进入客户特定的程序集中,以保持“核心”通用且不受阻碍通过依赖于客户特定的业务逻辑)。我们在内部调用这些插件,但它们更多的是构成整个产品的模块。
其工作方式是将这些模块的 DLL 复制到一个目录,然后应用程序运行时(ServiceStack IIS Web 应用程序或基于 Quartz 的控制台应用程序)执行 Assembly.LoadFile
对于不在已加载的当前程序集列表中的每个模块 (AppDomain.CurrentDomain.GetAssemblies()
)。
这个PluginLoader
仅加载 plugins.config
中存在的程序集文件,但我认为这与手头的问题几乎无关。PluginLoader
的完整代码类(class):
https://gist.github.com/JulianRooze/9f6d1b5e61c855579203
这....有效。有点。虽然它很脆弱,并且存在一个问题,即程序集以这种方式从不同的位置加载两次(通常来自应用程序的/bin/文件夹和插件目录)。这似乎是因为目前 PluginLoader
类被调用,AppDomain.CurrentDomain.GetAssemblies()
(在启动时)不一定返回程序将自行加载的程序集的最终列表。因此,如果/bin/中有一个名为 dapper.dll 的程序集(核心和许多插件/模块的共同依赖项)尚未被程序使用,那么它还没有被加载(换句话说:它会懒惰地加载它们)。然后,如果 dapper.dll 也是由插件提供的,PluginLoader
将看到它尚未加载并将加载它。然后,当程序使用它的 Dapper 依赖项时,它会从/bin/加载 dapper.dll,我们现在已经加载了两个 dapper.dll。
在大多数情况下,这似乎没问题。但是,我们使用 RazorEngine 库,当您尝试编译模板时,该库会提示具有相同名称的重复程序集。
在调查这个问题时,我遇到了这个问题:
Is there a way to force all referenced assemblies to be loaded into the app domain?
我尝试了接受的答案和 Jon Skeet 的解决方案。接受的答案有效(尽管我还没有验证是否有任何奇怪的行为)但感觉很讨厌。一方面,这也使程序尝试加载恰好位于/bin/中的 native DLL,这显然会失败,因为它们不是 .NET 程序集。所以你现在必须尝试-捕捉-吞下它。如果/bin/包含一些实际上不再使用但现在被加载的旧 DLL,我也担心奇怪的副作用。这在生产中不是问题,但它正在开发中(事实上,整个问题在开发中比在生产中更成问题,但在生产中也将赞赏解决此问题的额外稳健性)。
如前所述,我也尝试了 Jon Skeet 的回答,我的实现在 PluginLoader
的要点中可见。方法中的类LoadReferencedAssemblies
.这有两个问题:
System.Runtime.Serialization
找不到文件。 我还简要调查了使用托管可扩展性框架,但我不确定它是否适用。这似乎更旨在为加载组件和定义它们如何交互提供一个框架,而我实际上只对动态加载程序集感兴趣。
那么,鉴于要求“我想从目录中动态加载指定的 DLL 列表,而没有任何机会加载重复的程序集”,最好的解决方案是什么? :)
如果需要的话,我愿意彻底检查插件系统的工作方式。
最佳答案
有几种方法可以解决这个问题(模块/插件部署在目录层次结构中),坦率地说,您选择了最困难的。
最简单的一种是将所有文件夹添加到您的app/web.config 的私有(private)探测路径中。 .然后将所有调用替换为 Assembly.LoadFile
与 Assembly.Load .这将使 .NET 程序集解析机制自动为您解析所有程序集。您不需要加载引用的程序集,因为它们会在需要时自动加载。只有模块/插件必须使用 Assembly.Load
加载.
这种方法的缺点是当以下任一情况为真时:
AssemblyCatalog
中使用这种方法. 请注意,我不熟悉 ServiceStack。在 ASP.NET 中,您可以使用
Assembly.Codebase
属性(property)到load assemblies deployed outside of bin .最后看看 Suzanne Cook 在 LoadFile vs. LoadFrom 上的博客文章。 .
关于c# - 将程序集作为模块/插件加载,同时避免重复和脆弱性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19497831/