c# - .NET 中插件系统的动态对象实例化

标签 c# .net plugins .net-4.5

我正在开发一个需要通过插件模块支持自定义的系统。我针对接口(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();

所以我的问题有三个:

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

最佳答案

按顺序回答您的问题:

  1. 我喜欢这个,当我需要编写插件组件时我会使用这样的模式。其他人建议使用各种框架 - 我知道 MEF很受欢迎。但我发现使用 .NET 框架对我来说足够简单,学习 MEF 框架只是我需要学习和记住的另一件事。这可能值得一试,但取决于您。

  2. 我一直使用 Assembly.CreateInstance,但差异可能不会影响您 ( Difference between Assembly.CreateInstance and Activator.CreateInstance? )

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

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

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

关于c# - .NET 中插件系统的动态对象实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15419754/

相关文章:

c# - 在 C# 的泛型方法中使用枚举

c# - 事件+适配器模式

c# - 我需要固定匿名代表吗?

c# - 如何配置 Fluent NHibernate 在使用 ReferencesAny 时返回 null 而不是丢失对象的代理

.net - 从 .NET 数据库中检索数据的最快方法?

c# - Orderby 不调用提供的比较器的 Compare()

javascript - Com 类型编码(marshal)处理 - C# Windows 运行时组件 - Cordova 项目 Javascript 调用 - Cordova Windows 插件

c# - 将 IQueryable 作为参数传递

html - 如何为 linux 配置基于浏览器的 vlc 插件

java - JoinMessages 类型必须实现继承的抽象方法 CommandExecutor.onCommand(CommandSender, Command, String, String[])