如何使用c#处理插件系统?

时间:2017-09-16 20:33:55

标签: c# plugins

我正在尝试为我的应用程序创建一个插件系统,以便人们可以开发附加组件。这对我来说是一个新概念。经过几个晚上的学习,我得到了装载系统。现在我正在努力学习如何使我的界面允许插件开发人员扩展应用程序?

简单的例子可以让我走上正确的轨道

我有一个全局字符串

string Filters = "csv files (*.csv)|*.csv";

现在我如何允许插件开发人员扩展此字符串以允许所有看起来像这样的文件

string Filters = "csv files (*.csv)|*.csv|All Files (*.*)|*.*";

我当前的插件界面如下所示

namespace CSV_Analyzer_Pro.Core.PluginSystem {
    public interface IPlugin {
        string Name { get; }
        string Version { get; }
        string Description { get; }
        void Action();
    }
}

加载应用程序时,插件文件夹中包含的所有插件都会像这样加载

    PluginLoader loader = new PluginLoader();
    loader.LoadPlugins();
    loader.Init();
}catch(Exception exc) {
    Console.WriteLine(string.Format("Plugins couldnt be loaded: {0}", exc.Message));
}

加载插件后,您会注意到loader.Init()被调用,调用每个插件的Action()

public void Init() {
    if(Plugins != null) {
        Plugins.ForEach(plugin => plugin.Action());
    }
}

所有这些设置到位后,如何开始允许插件扩展功能?

我的主要目标是让插件开发人员能够向应用程序添加其他功能以及修改现有功能。我最麻烦的是如何动态获取所有这些信息?

我意识到我应该向插件询问信息,但我正在努力解决"这个插件是否存在?"我真的不明白插件系统背后的概念,以允许"社区"以他们认为合适的方式扩展应用程序

例如,您的基本应用程序具有menustrip。他们如何向menustrip添加新项目?我是否必须对允许通过插件扩展的所有内容进行硬编码?我不愿意。我想允许完全可扩展性而不会对开发方产生太大干扰。

我确实看过MEFMAF,但文档确实令人困惑,我所做的所有研究基本上只是如何查找和加载插件的教程,他们创建了一个简单的控制台应用程序。没有人知道如何允许插件开发人员通过插件扩展应用程序。

我意识到这是一项艰巨的任务而且不容易实现,但我已经为加载和注册插件奠定了基础,现在我只需要知道如何使其符合我的需要。

此处还有PluginLoader类,以防它将内容置于上下文中

namespace CSV_Analyzer_Pro.Core.PluginSystem {
    public class PluginLoader {
        public static List<IPlugin> Plugins { set; get; }

        public void LoadPlugins() {
            Plugins = new List<IPlugin>();

            if (Directory.Exists(Constants.PluginFolder)) {
                string[] files = Directory.GetFiles(Constants.PluginFolder);
                foreach(string file in files) {
                    if (file.EndsWith(".dll")) {
                        Assembly.LoadFile(Path.GetFullPath(file));
                    }
                }
            }

            Type interfaceType = typeof(IPlugin);

            Type[] types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()).Where(p => interfaceType.IsAssignableFrom(p) && p.IsClass).ToArray();

            foreach(Type type in types) {
                Plugins.Add((IPlugin)Activator.CreateInstance(type));
            }
        }

        public void Init() {
            if(Plugins != null) {
                Plugins.ForEach(plugin => plugin.Action());
            }
        }
    }
}

0 个答案:

没有答案