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: 🙂