【问题标题】:How can I create a plugin mechanism that calls functions only when the plugin is available?如何创建仅在插件可用时才调用函数的插件机制?
【发布时间】:2013-02-18 08:37:44
【问题描述】:

对不起,如果我不够清楚,我很难写出这个问题。

我下载了一个开源软件。我想扩展功能,所以我想创建模块来封装这些模块的功能,这些模块将是 .dll 文件。 我希望有一个完全独立于另一个:如果我在配置文件中将一个键设置为 true,并且如果文件夹中存在 DLL,则应该加载插件。

问题是:如何动态调用插件(只应用插件调用)?

如果我直接引用插件类,我将不得不引用插件 dll,但我希望能够在没有插件的情况下运行核心软件。是否有任何设计模式或其他机制允许我仅在应用插件的情况下加载和使用 DLL,并且仍然可以在没有插件的情况下运行核心软件?

【问题讨论】:

    标签: c# design-patterns architecture asp.net-mvc-4


    【解决方案1】:

    有多种方法可以实现这一点,我将在这里描述一个简单的解决方案。

    制作每个插件必须实现的通用接口,以便与核心应用程序集成。这是一个例子:

    // Interface which plugins must implement
    public interface IPlugin
    {
      void DoSomething(int Data);
    }
    
    // Custom plugin which implements interface
    public class Plugin : IPlugin
    {
      public void DoSomething(int Data)
      {
        // Do something
      }
    }
    

    要真正从 dll 加载你的插件,你需要使用反射,例如:

    // Load plugin dll and create plugin instance
    var a = Assembly.LoadFrom("MyCustomPlugin.dll");
    var t = a.GetType("MyCustomPlugin.Plugin");
    var p = (IPlugin)Activator.CreateInstance(t);
    
    // Use plugin instance later
    p.DoSomething(123);
    

    您可以为插件程序集和类使用某种命名约定 这样您就可以轻松加载它们。

    【讨论】:

    • 我只想补充一点,如果您不希望发生任何事情,您可以创建一个默认插件的DoNothing 实现。
    • 这是我想采取的方法。只有一个(愚蠢的)问题:如果我必须返回一些值,那么这个类就必须在我的核心项目中。有什么办法可以规避吗?
    • 如果您需要返回某个自定义类的对象的结果,那么这个自定义类必须对核心应用项目和插件项目都可见。这是一个简单的例子: ProjectA - 核心应用程序实现; ProjectP - 自定义插件实现; ProjectC - 用于核心应用程序和自定义插件之间通信的东西。诸如 IPlugin、PluginResult 之类的东西……; ProjectA 和 ProjectP 都引用了 ProjectC。
    【解决方案2】:

    您可以使用MEF

    托管可扩展性框架 (MEF) 是一个组合层,用于 .NET 提高了灵活性、可维护性和可测试性 大型应用程序。 MEF 可用于第三方插件 可扩展性,或者它可以带来松耦合的好处 普通应用程序的插件式架构。

    Here 是编程指南。

    【讨论】:

      【解决方案3】:

      .NET 术语中的插件或 DLL 称为程序集。查看 Assemply.Load 方法,以及 this guide in msdn

      【讨论】:

        【解决方案4】:

        System.Reflection namespace 提供了许多工具来帮助您解决这种情况。

        你可以

        • 检查程序集(DLL 文件)以检查其中的对象,
        • 找到您要查找的类型(特定类、实现特定接口的类等)
        • 创建这些类的新实例,并
        • 调用这些类的方法和访问属性。

        通常你会在扩展中编写一个类来做一些工作,创建一个方法(例如DoWork()),然后动态调用该方法。

        这个问题中提到的 MEF 正是这样做的,只是有更多的框架。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-17
          • 2014-09-01
          • 1970-01-01
          • 1970-01-01
          • 2016-01-20
          • 2014-03-29
          相关资源
          最近更新 更多