. 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();

我的问题有三个:

  1. 插件系统的推荐模式是什么?我所采用的方法是否有意义,或者是否存在明显的缺陷/警告?
  2. Activator.CreateInstance()是动态实例化插件对象的好选择?
  3. 我怎样才能更具体地了解要加载的程序集及其位置?例如,如果我只想从位于.'plugins子文件夹中的程序集加载插件。

. net插件系统的动态对象实例化

回答您的问题,按顺序排列:

  1. 我喜欢这样,当我需要编写插件组件时,我使用这样的模式。其他人建议使用各种框架——我知道MEF非常流行。但是我发现使用。net框架对我来说很容易,而学习MEF框架只是我需要学习和记住的另一件事。这可能值得一试,但取决于你。

  2. 我一直使用Assembly.CreateInstance,但差异可能不会影响你(汇编之间的差异。

  3. 您只需使用System.IO命名空间。DirectoryInfo类有一个方法,枚举与给定模式匹配的所有文件(假设是*.dll)。对于每个匹配,我会使用System.Reflection命名空间来查询并找到实现您的接口的任何类型,然后使用CreateInstance

就MEF而言,我的观点是:如果我要在许多系统或项目中使用一个大型的、可管理的和灵活的插件系统,那么我会对它非常感兴趣,利用其他人所做的工作来节省时间并避免常见的陷阱。

如果我正在编写一个非常简单的一次性插件系统,并且我知道如何使用。net框架这样做的基础知识,我会跳过学习MEF的开销并编写代码。我可以在不到一个小时的时间内编写一个合理的插件过程,但是在下载,引用,尝试配置MEF之后-我怀疑我有什么可以展示的。