Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Wie binde ich das dynamische Laden von Plugins in den Programmablauf ein?
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 228

Themenstarter:

Wie binde ich das dynamische Laden von Plugins in den Programmablauf ein?

beantworten | zitieren | melden

Hi,

leider finde ich zum Thema Plugins nicht viel. Zumindest wenn es über eine Funktion aufrufen hinausgehen soll.
Mein Problem ist nicht das Laden der DLLs usw. sondern die Architektur des Programmes.

Mein Ansatz war bisher folgender:

Ich habe ein Interface des Pluginhosts (das stellt mein Hauptprogramm dar). Die Plugins bekommen das PluginHost Objekt übergeben und können sich an Events binden oder später auch darüber auf Datenbank, etc. zugreifen.


    public interface IPluginHost
    {
        event EventHandler ApplicationStarted;

    }

Mein Hauptprogramm erstellt sich dann das Hostobjekt und triggert die Events bei Bedarf bzw. stellt später die Felder zur Verfügung.



    public class PluginHost : IPluginHost
    {
        private List<IPlugin> _plugins = new List<IPlugin>();

        public event EventHandler ApplicationStarted;

        public virtual void OnApplicationStarted(EventArgs e)
        {
            EventHandler handler = ApplicationStarted;
            handler?.Invoke(this, e);
        }


        public PluginHost()
        {
            // Test-Plugin laden:
            _plugins.Add(new TestPlugin.MyPlugin(this));
            

        }
    }

// in der Application_Startup z.B.:
private void Application_Startup(object sender, StartupEventArgs e)
{
            // Plugin Host initalisieren:
            PluginHost pluginHost = new PluginHost();

            // ... Programm lädt ....

            // Execute Plugin ApplicationStarted:
            pluginHost.OnApplicationStarted(e);
 }



Das Plugin sieht dann z.B. so aus:



    public class MyPlugin : IPlugin
    {


        public MyPlugin(IPluginHost host)
        {
            host.ApplicationStarted += Host_ApplicationStarted;
        }

        public string Title => "Test-Plugin";

        private void Host_ApplicationStarted(object sender, EventArgs e)
        {
            Debug.WriteLine("Ich bin auch da!");
        }
    }



Jetzt meine Frage, gibts da soweit bessere Möglichkeiten das umzusetzen?

Wenn ich jetzt z.B. Plugins die Möglichkeit geben will ein MenuItem zu bekommen, habe ich das mal so gesehen:
Das heißt die rufe die Funktionen im Plugin auf und sie können mir ein Item zurückgeben oder eben Null.


    public enum Menu
    {
        MainFile,
        MainExtra,...
    }

    public interface IPluginHost
    {
        event EventHandler ApplicationStarted;
        MenuItem GetMenuItem(Menu place);

    }

Wäre das soweit alles, auch in Bezug auf .NET Core richtig oder habt ihr bessere Beispiele/Ideen?
Da das alles ziemlich tief in den Programmablauf eingebunden wird will ich es natürlich auch richtig machen
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15703
Herkunft: BW

beantworten | zitieren | melden

Zitat von JimStark
Jetzt meine Frage, gibts da soweit bessere Möglichkeiten das umzusetzen?
Besser ist immer relativ; kommt auf die Anforderungen an, die halt nur Du kennst.
Du hast hier ja nich mal ein Wort verloren, welche Art von Anwendung Du überhaupt hast.
Zitat von JimStark
Wäre das soweit alles, auch in Bezug auf .NET Core richtig oder habt ihr bessere Beispiele/Ideen?

Kommt auf die Art der Anwendung und auf die Anforderungen an, die eben - auch hier - nur Du kennst.
Zitat von JimStark
will ich es natürlich auch richtig machen :D
Richtig ist etwas immer nur solange, bis es eine Anforderungsänderung gibt, die was neues erfordert.
Daher such Dir eine Lösung, die einfach ist und die Anforderungen erfüllt.

Macht kein Sinn sofort die Weltbeste Lösung zu programmieren, die man vielleicht niemals braucht.
private Nachricht | Beiträge des Benutzers
T-Virus
myCSharp.de - Member



Dabei seit:
Beiträge: 1820
Herkunft: Nordhausen, Nörten-Hardenberg

beantworten | zitieren | melden

Die Anforderung ist hier zu spezifisch und auch nur in deinem Anwendungsfall sinnvoll.
Welche Lösung sollte man dir hier anbieten können?
Eine Allgemeine Lösung für Plugins und deren Umsetzung, hängt wie immer von dem konkreten Anwendungsfall ab.

T-Virus
Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
private Nachricht | Beiträge des Benutzers
JimStark
myCSharp.de - Member

Avatar #dOpLzh7hN1az1g0eGRc0.jpg


Dabei seit:
Beiträge: 228

Themenstarter:

beantworten | zitieren | melden

Okay, danke euch beiden. Dachte es würde evtl. einen eleganteren Weg, Pattern, etc. geben.
Dann werde ich es erstmal so machen.

Eine Frage noch zu diesem Thema. Vielleicht kann man es auch in einen eigenen Thread trennen:


Ich habe ein ViewModel mit den Controls der Plugins. z.B.:



public class PluginsViewModel : BaseViewModel
{
      private List<MenuItem> _ContextMenuItems;
      public List<MenuItem> ContextMenuItems { get { return _ContextMenuItems; }}
...
}


Darin fülle ich dann, falls vorhanden, die von den Plugins zurückgegeben MenuItems.


Jetzt kann ich per XAML ja direkt die Items binden:


<MenuItem Header="Extras" ItemsSource="{Binding MyPluginsViewModel.ContextMenuItems}"/>

Gibt es einen Weg wenn ich per XAML schon Subitems definiert habe diese noch zu Erweitern? Ohne Codebehind und ohne die bereits vorhandenen Items im ViewModel dynamisch hinzuzufügen.


<MenuItem Header="Extras">
   <MenuItem Header="Bla">
   ...
   // Hier die ContextMenuItems hinzufügen
</MenuItem>

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von JimStark am .
private Nachricht | Beiträge des Benutzers