Einfaches Plugin-System erstellen in C#

Die Erstellung eines Plugin-System ist grundlegend recht simpel. Fangen wir zunächst mit unserer Schablone an.
Diese besteht aus einem Interface mit einigen Eigenschaften:

    public interface IPluginBase
    {
        public String Name { get; set; }
        public String Description { get; set; }

        public ObservableCollection<object> DynamicValues { get; set; }

        public PluginResponse Initialize(PluginParameters args);

        public PluginResponse Execute(PluginParameters args);
    }

Die Übergabeparameter für die Initialisierung des Plugins sowie die Antwort des Plugins lagern wir in eigene Klassen aus:

    public class PluginParameters
    {
        public DbConnection con { get; set; } = null;
        public HashSet<object> Context { get; set; } = new HashSet<object>();
    }

    public class PluginResponse
    {
        public String Message { get; set; } = "";
        public Boolean HasError { get; set; } = false;
        public String MessageID { get; set; } = "";

        //...
    }

Um die Plugins dann zur Laufzeit einzulesen benötigen wir einen Plugin-Manager:

    public class PluginManager
    {
        private HashSet<String> DirectoryPaths = new HashSet<string>();
        public HashSet<IPluginBase> CurrentPlugins = new HashSet<IPluginBase>();

        public PluginManager(String DirectoryPath)
        {
            DirectoryPaths.Add(DirectoryPath);
            LoadPlugins();
        }

        public PluginManager(List<String> DirectoryPaths)
        {
            this.DirectoryPaths = new HashSet<string>(DirectoryPaths);
            LoadPlugins();
        }

        public void LoadPlugins()
        {
            CurrentPlugins = new HashSet<IPluginBase>();

            foreach(var ele in DirectoryPaths)
            {
                DirectoryInfo dir = new DirectoryInfo(ele);

                foreach (FileInfo file in dir.GetFiles("*.dll"))
                {
                    Assembly ass = Assembly.LoadFrom(file.FullName);
                    foreach(Type t in ass.GetTypes())
                    {
                        if((t.IsSubclassOf(typeof(IPluginBase)) || t.GetInterfaces().Contains(typeof(IPluginBase))) && t.IsAbstract == false)
                        {
                            IPluginBase b = t.InvokeMember(null,
                                                BindingFlags.CreateInstance, null, null, null) as IPluginBase;

                            CurrentPlugins.Add(b);
                        }
                    }

                }

            }
        }
    }

Diesen Plugin-Manager können wir dann in unserem Programm einsetzen:

        private PluginManager manager = null;

        public MainWindowViewModel()
        {
            manager = new PluginManager("plugins");
            foreach(var ele in manager.CurrentPlugins)
            {
                PluginEntry ent = new PluginEntry(ele);
                MenuItems.Add(ent);
            }

            ExamplePlugin example = new ExamplePlugin();
            MenuItems.Add(new PluginEntry(example));
        }

Wer zu faul ist, sich ein eigenes Plugin-System zu programmieren kann auch unser .NET-Core-NuGet verwenden!

Die ganze Anleitung auch als Video unter YouTube: 🙂