c# - How to make app pluggable by add/remove a plugin file? -
assume have plugin interface this:
// plugininterface.cs interface plugin { bool check_when_loaded(string q); } static class pluginlist { public static list<plugin> list = new list<plugin>(); }
and use in mainwindow.cs:
// mainwindow.cs private void window_loaded(object sender, routedeventargs e) { foreach (var p in pluginlist.list) { if (p.check_when_loaded(q.text)) break; } }
assume write plugin lovelyplugin.cs
:
// lovelyplugin.cs class lovelyplugin : plugin { public bool check_when_loaded(string q) { return true; } }
what need when add lovelyplugin.cs
c# project complie, 'lovelyplugin' instance added automaticly pluginlist.list
, , if remove file complie, there no trace of lovelyplugin
in application @ all.
i have c# solution have simliar project (light, standard, extra,...). difference between them 1 have or doesn't have plugin file. .cs
files add link these project , want build these project concurently.
i can use #define
, #if
condition build each project seperately. wonder if there way fit need by add/remove plugin file without make change in other source code file each project. appreciated!
you use mef...
start referencing system.componentmodel.composition
read on mef documentation regarding imports , exports. in case, plugins "exports". can use [inheritedexport] attribute allow every concrete object implements iplugin exportable.
// iplugin.cs using system.componentmodel.composition; [inheritedexport] public interface iplugin { bool check_when_loaded(string q); }
your concrete implementation of iplugin doesn't change.
// lovelyplugin.cs class lovelyplugin : iplugin { public bool check_when_loaded(string q) { return true; } }
i eliminated static pluginlist class simplify example. below can see how main form "importing" implmentations of iplugin found in assembly. if add (or remove) additional concrete implementations of iplugin , recompile, list reflect accordingly.
// mainwindow.cs using system.componentmodel.composition; using system.componentmodel.composition.hosting; using system.reflection; public partial class form1 : form { [importmany] public list<iplugin> list = new list<iplugin>(); public form1() { initializecomponent(); } private void windowloaded(object sender, eventargs e) { var catalog = new assemblycatalog(assembly.getexecutingassembly()); var container = new compositioncontainer(catalog); container.composeparts(this); foreach (var p in list) { if (p.check_when_loaded(this.name)) break; } } }
Comments
Post a Comment