[c#] Plugin Framework Konzept

Halfbax

Erfahrenes Mitglied
Mahlzeit,

nach einigen Anläufen und niederlegen alter Versuche möchte ich einen neuen, besser organisierten Versuch starten. Dieses mal möchte ich vorher ein ordnetliches Konzept vor dem Manne haben. Dieses möchte ich auch mit euch besprechen.

Ich möchte ein Plugin Framework für den persönlichen und learning-by-doing Gebrauch erstellen und auf fertige APIS verzichten o.ä.

Da meine anderen Versuche meistens an dem dynamischen Einbinden gescheitert sind. Dachte ich mich frag ich vorher mal hier was Ihr von diesem Entwurf haltet, oder ob Ihr noch etwas einführen wollt (sehr wahrscheinlich habe ich einiges vergessen *facepalm* ).

plugin-konzept.png


Bitte um Kritik :)

Mit freundlichen Grüßen
Halfbax
 

Spyke

Premium-User
Eigentlich gibts nixs weiter zu sagen.
Eine Plugin Schnittstelle welche die Plugins setzen und entsprechenden Handler der die Plugins lädt.

Im Grunde ist nur die Frage wie du die Plugin findest.

ILSpy zum Beispiel (aber grad nicht ganz sicher) durchsucht glaube die DLLs die in seinem Ausführungsverzeichnis liegen ob die DLLs dort Typen mit entsprechender Schnittstelle haben.

Bei uns im Haus, bei unserem Plugin System, haben wir einfach ne XML in der steht dll und Plugin Typ.
 

Turri

Erfahrenes Mitglied
Hallo,

bzgl. Plugins dynamisch zur Laufzeit laden, schau dir mal dieses MEF-Tuto (Managed Extensibility Framework) an.
MEF sucht die Plugins für dich, du musst nur einen Ordner angeben wo die dlls (mit entsprechenden Interfaces) liegen (suchen dann mit einem "DirectoryCatalog").
Weitere Infos gibts hier: http://www.just-about.net/mef-tutorial

Vielleicht hilft es dir ja weiter.
 

Halfbax

Erfahrenes Mitglied
Im Grunde ist nur die Frage wie du die Plugin findest.

ILSpy zum Beispiel (aber grad nicht ganz sicher) durchsucht glaube die DLLs die in seinem Ausführungsverzeichnis liegen ob die DLLs dort Typen mit entsprechender Schnittstelle haben.

Ich arbeite derzeit mit folgenden Algorithmus, da alle Plugins in einem bestimmten Unterordner sind.
C#:
            // Erst werden alle plugins geladen mittels Assembly.LoadFrom()          

            foreach(Assembly a in AppDomain.CurrentDomain.GetAssemblies())
                foreach(Type t in a.GetTypes())
                    if(t.GetInterface("ISPlugin") != null)
                    {
                        // ToDo Activator.CreateInstance() ....
                    }

Nachtrag: Ich frage mich, wie kann ich das Eventhandling so dynamisch wie möglich gestalten? Ich hatte mir gedacht, man könnte ein onEvent-registrieren und im Verlauf die Namen der Events vergleichen, sofern diese stimmen -> wird es ausgeführt. Was sagt Ihr dazu?
 
Zuletzt bearbeitet:

Spyke

Premium-User
Ich verstehe die Frage im Nachtrag nicht.
Sind das nicht events die durch die schnittstelle mit bereitgestellt werden.
Diese einfach normal abonnieren.
 

Halfbax

Erfahrenes Mitglied
Ich verstehe die Frage im Nachtrag nicht.
Sind das nicht events die durch die schnittstelle mit bereitgestellt werden.
Diese einfach normal abonnieren.
Ich möchte das gerne unabhängig gestalten, sodass im Plugin jegliches Event bereitgestellt werden kann und sofern das Endprogramm z.V stellt auch nutzt.
 

Spyke

Premium-User
schmeißen die plugins das event oder dein programm?

wenn die plugins das event schmeißen, eifnach abonnieren, entweder wird geschmießen oder nicht

wenn das programm irgendwas auslösen soll,
reicht es wenn in der schnittstelle einfach entsprechende methode breitsteht welche dein programm dann nur auslöst/aufruft
 

Halfbax

Erfahrenes Mitglied
Hatte mir das so gedacht: Im Programm wird irgendein Event ausgelöst, der Handler triggert das und durchsucht alle Events in allen Plugins, falls eins mit dem selben Namen da ist wird es ausgelöst.
 

ComFreek

Mod | @comfreek
Moderator
Wenn du sehr flexibel sein möchtest, dann kannst du ein ähnliches Konzept wie im Browser verfolgen:
Javascript:
document.addEventListener("generischer String Name für das Event", function () { ... });
In deiner Hauptanwendung hast du z. B. eine Map von Listen (Map<String, List<CallbackInfo>>).
 

Spyke

Premium-User
aufbauend auf ComFreeks Vorschlag.

Hier mal ein kleiner abgespeckter Teil aus einem meiner projekte.
In diesem wird dynamisch ein Typ geladen und isntanziiert und von diesem ein Ereignis abonniert

per Reflection Typ laden
Code:
            Assembly assembly = Wrapper.GetAssembly();

            refObjectType = assembly.GetType("MeinTyp");
            refObject = (IDisposable)Activator.CreateInstance(refObjectType, new object[] {  });

            EventInfo meinEventInfo = refObjectType.GetEvent("MeinEvent", BindingFlags.Public | BindingFlags.Instance);
            MethodInfo ownMethod = this.GetType().GetMethod("meinTyp_MeinEvent", BindingFlags.Instance | BindingFlags.NonPublic);

            meinEventHandler = Delegate.CreateDelegate(meinEventInfo.EventHandlerType, this, ownMethod);
            meinEventInfo.AddEventHandler(refObject,  meinEventHandler);

methode im Programm die an das event weiter gegeben wird
Code:
        private void meinTyp_MeinEvent(object sender, EventArgs e)
        {
            //tu was
        }