. net插件系统的动态对象实例化
本文关键字:对象 实例化 动态 插件 系统 net | 更新日期: 2023-09-27 18:03:53
我正在开发一个需要通过插件模块支持定制的系统。我对接口进行编码,以便插件代码只需要实现这些接口,以便能够插入系统。
// 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
,但差异可能不会影响你(汇编之间的差异。 -
您只需使用
System.IO
命名空间。DirectoryInfo
类有一个方法,枚举与给定模式匹配的所有文件(假设是*.dll
)。对于每个匹配,我会使用System.Reflection
命名空间来查询并找到实现您的接口的任何类型,然后使用CreateInstance
。
就MEF而言,我的观点是:如果我要在许多系统或项目中使用一个大型的、可管理的和灵活的插件系统,那么我会对它非常感兴趣,利用其他人所做的工作来节省时间并避免常见的陷阱。
如果我正在编写一个非常简单的一次性插件系统,并且我知道如何使用。net框架这样做的基础知识,我会跳过学习MEF的开销并编写代码。我可以在不到一个小时的时间内编写一个合理的插件过程,但是在下载,引用,尝试配置MEF之后-我怀疑我有什么可以展示的。