我正在开发一个需要通过插件模块支持自定义的系统。我针对接口(interface)进行编码,以便插件代码只需要实现这些接口(interface)就能够插入系统。
// for illustration purposes; not actual code
public interface IPluggable
{
void Setup(PluginConfig c);
bool Process(IProcessable p);
}
我从配置中读取需要加载的插件,其中指定了程序集名称和完全限定类型名称。
<plugin assembly="Foo.Bar.PluginAssembly" type="Foo.Bar.Plugins.AwesomePlugin" />
其中类型 Foo.Bar.Plugins.AwesomePlugin
实现 IPluggable
并包含在程序集 Foo.Bar.PluginAssembly.dll
中。有了这些信息,我就可以继续创建所需插件的实例。
IPluggable plugin = (IPluggable)Activator.CreateInstance(assemblyName, typeName).Unwrap();
所以我的问题有三个:
- 插件系统的推荐模式是什么?我采取的方法是否有意义,或者我是否遗漏了任何明显的缺陷/警告?
Activator.CreateInstance()
是动态实例化插件对象的好选择吗?- 如何更具体地了解要加载的程序集及其位置?假设我只想从位于
.\plugins
子文件夹中的程序集加载插件。
最佳答案
按顺序回答您的问题:
我喜欢这个,当我需要编写插件组件时我会使用这样的模式。其他人建议使用各种框架 - 我知道 MEF很受欢迎。但我发现使用 .NET 框架对我来说足够简单,学习 MEF 框架只是我需要学习和记住的另一件事。这可能值得一试,但取决于您。
我一直使用
Assembly.CreateInstance
,但差异可能不会影响您 ( Difference between Assembly.CreateInstance and Activator.CreateInstance? )您只需使用
System.IO
命名空间即可。DirectoryInfo
类有一个方法,可以枚举与给定模式(大概是*.dll
)匹配的所有文件。对于每场比赛,我都会使用System.Reflection
命名空间来询问并查找实现您的接口(interface)的任何类型,然后CreateInstance
。
就 MEF 而言,我的观点是这样的:如果我要在许多系统或项目上使用大型、可管理且灵活的插件系统,那么我会对它非常感兴趣,利用它的工作其他人这样做是为了节省时间并避免常见的陷阱。
如果我正在编写一个非常简单的一次性插件系统,并且我知道如何使用 .NET 框架实现这一点的基础知识,我会跳过学习 MEF 的开销并编写代码。我可以在不到一个小时的时间内编写一个合理的插件流程,但是在下载、引用、尝试配置 MEF 之后 - 我怀疑我是否有任何东西可以展示。
关于c# - .NET 中插件系统的动态对象实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15419754/