Wie erstelle ich ein PlugIn System unter VB.NET (Framework 2)

    • VB.NET

    Es gibt 47 Antworten in diesem Thema. Der letzte Beitrag () ist von Linkai.

      Hallo,

      ich wollte mal fragen, ob man da auch irgendwie Events mit Einbauen kann.
      Also das ich mit der Host-Anwendung ein Event im Interface eines Plugins auslösen kann und das ich aus einem Plugin ein Event in der Host-Anwendung auslösen kann.

      MfG pc-freack
      ich habe das so gemacht:

      VB.NET-Quellcode

      1. Public Class Form1
      2. Private myplugin As [interface].PluginInterface
      3. Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
      4. Dim PlugIns As New List(Of [interface].PluginInterface)
      5. For Each plug As String In Directory.GetFiles(Application.StartupPath & "\Plugins", "*.dll")
      6. Dim PlugIn As [interface].PluginInterface = PlugInConnector.LoadPlugIn(plug)
      7. If Not (PlugIn Is Nothing) Then
      8. PlugIns.Add(PlugIn)
      9. ListBox1.Items.Add(PlugIn.Name)
      10. End If
      11. Next
      12. If myplugin Is Nothing Then
      13. MessageBox.Show("Kein gültiges PlugIn gefunden !")
      14. Me.Close()
      15. End If
      16. End Sub
      17. End Class

      [vbPublic Class myClient
      Implements [interface].PluginInterface

      Public ReadOnly Property Name As String Implements [interface].PluginInterface.Name
      Get
      Return "kkk"
      End Get
      End Property
      End Class][/vb]

      nur er läd kein plugin und es kommt die nachricht das kann gülties plugin verfügbar sei obwohl mein plugin korrekt ist?

      kann mir da jemand helfen?

      filmee24 schrieb:

      kann mir da jemand helfen?

      Wie sieht denn der Inhalt Deines PlugIn-Verzeichnisses aus?
      Die eigentliche Interface-DLL muss da nämlich auch drin liegen.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      Hallo,
      ich finde dieses Plugin System recht Simpel und gut.
      Jedoch ergibt sich bei mir ein paar fragen:

      - Ich gehe mal von folgendem Standpunkt aus: Host Project hat eine Form -> 3 Tabs -> mit txtboxen etc...
      - mein Interface beinhaltet die ganzen Funktionen etc.
      - mein Client beinhaltet den ganzen Code für diese 3 Tabs...mit txtboxen usw.

      Also im Endeffekt ein Programm was genauso wie im 1 Beispiel aufgebaut ist und funktioniert...


      Jetzt stell ich mir die Frage:

      Was ist wenn ich einen 4 Tab erstellen möchte...

      1. Ich passe die Interface DLL an
      2. Ich passe die Client DLL an

      Soweit ist es klar
      Aber da sich ja so wie im 1 Beispiel in der Host Datei die entsprechende Form befindet muss ich doch auf der Form den 4 tab erstellen und mit meinen Elementen aufbauen...
      Somit heißt es ja das ich die Host ebenfalls neu Kompilieren muss wodurch sich doch eh wieder die EXE verändert...
      Oder etwa nicht?

      Theoretisch müsste der Aufbau doch folgender sein:
      Host Datei = leere Form (Main EXE)
      Interface Datei -> Hier befindet sich die form -> Erweiterbar ohne die Main EXE neu machen zu müssen
      Funktions Datei -> Funktionen erweiterbar für die Interface Datei
      Client Datei -> Naja der eigentliche Code...

      Dieser Aufbau würde das Problem der Form etc umgehen ...

      Oder habe ich da etwas falsch verstanden

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Dodo“ ()

      guck dir mal deine FormName.Designer.vb an, wie dort die Tabs erstellt werden, in Wirklichkeit passiert das alles zur Laufzeit, solch einen Code kannst du auch in dein Plugin einbauen(mit Zugriff auf das jeweilige Formular), dadurch kannst du ebenfalls einen solchen Tab erstellen lassen...
      Ich wollte auch mal ne total überflüssige Signatur:
      ---Leer---
      Hi,
      ich habe mich nun endlich mal näher mit diesem System befasst. Nachdem mir das doch noch einmal empfohlen wurde. Ein dank @ RodFromGermany

      Das System funktioniert so wie es ist an und für sich sehr gut. Zumindest dahingehen bis ich versuche ein 2 Plugin zu erstellen.
      Da ich ein blutiger anfänger bin verstehe ich nich so 100%ig wie das funktioniert mit dem Interface und dem Client.

      Hier einmal ein versuch:

      myInterface

      VB.NET-Quellcode

      1. Function hallowelt(ByVal hallo As String, ByVal welt As String) As String

      Hier habe ich unter der 1. Funktion einfach mal eine 2 hingeschrieben...

      Anschließend habe ich eine neue ClassLibary mit dem namen hallo.vb erstellt und wollte das Interface implementieren...
      Tjo wie es kommen musste macht er das zwar aber er wollte unbedingt die Funktion mit dem Addieren ebenfalls drin haben ... also nich sinn der sache ....

      nochmal zurück zum Interface:

      VB.NET-Quellcode

      1. Public Interface myhallowelt 'z.b. funktion
      2. Function hallowelt(ByVal hallo As String, ByVal welt As String) As String
      3. End Interface


      ich habe einfach mal zum testen ein 2 Public Interface geschrieben... siehe oben...
      Also wieder die neue VB Datei Hallo.vb öffnen und befüllen

      VB.NET-Quellcode

      1. Public Class hallowelt Implements [Interface].myhallowelt
      2. Public Function hallowelt(hallo As String, welt As String) As String Implements [Interface].myhallowelt.hallowelt Return hallo + welt End FunctionEnd Class



      Tja soweit sieht es ganz gut aus... aber jetzt bekomme ich Probleme mit meiner Host Datei...
      Theoquasi müsste ich nach dem

      VB.NET-Quellcode

      1. Private myplugin As [Interface].myInterface


      ein

      VB.NET-Quellcode

      1. Private myplugin2 As [Interface].myhallowelt


      hinzufügen und schon sollte die Host Datei eigentlich alles machen..

      Aber was soll nu die Datei überhaupt machen.. Also ich habe in der Form 2 Textfelder und 1 Button 1Label hinzugefügt. In der form_load() habe ich folgendes geschrieben

      VB.NET-Quellcode

      1. Me.TextBox1.Text = "test1" Me.TextBox2.Text = "test2"


      Der Button hat folgendes bekommen

      VB.NET-Quellcode

      1. Me.Label4.Text = myplugin2.hallowelt(CStr(Me.TextBox2.Text), CStr(Me.TextBox1.Text))



      Jetzt sollte er eigentlich den Text aus den Textfeldern nehmen und zusammensezten.. und im Label4 wieder Ausgeben... Doch da bekomm ich beim Click auf den Button nur ein NullReferenceException..

      Tjo jetzt stell ich mir die Frage wie muss ich ein Plugin zusammenbauen...
      Hallo,
      Ich wollte mir mittels dem Tutrorial ein kleines Pluginsystem basteln. Wenn ich jedoch wie im Tutorial beschrieben Implements [Interface].myInterface schreibe, bekomme ich Meldungen die alle so sind:
      Der Typ Interface.MyInterface ist nicht Definiert

      Code:

      VB.NET-Quellcode

      1. Public Class Class1
      2. Implements [Interface].myInterface
      3. Public Function Addieren(ByVal zahl1 As Integer, ByVal zahl2 As Integer) As Integer Implements [Interface].myInterface.Addieren
      4. Return zahl1 + zahl2
      5. End Function
      6. Public ReadOnly Property Datum() As Date Implements [Interface].myInterface.Datum
      7. Get
      8. Return Now
      9. End Get
      10. End Property
      11. End Class

      Jeder DLL, die das Interface implementiert, muss die Interface-Interface-DLL natürlich als Verweis hinzugefügt werden, damit das Syste, weiß, wovon die Rede ist.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      So, mir ist jetzt beim Nachbau etwas aufgefallen: Man(n) muss also jedes mal wenn man ein Plug-In programmiert haben, das Interface ändern, weil im Interface sind die ja die ganzen Prozeduren des eigentlichen Plug-Ins niedergeschrieben. Ist das so richtig ?

      Und wie kann man neues Fenster mit einbinden ?

      Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „DerHans117“ ()

      Das wäre gegen das Konzept eines PlugIn-Systems.
      Du erstellst das Inteface einmal. Fertig.
      Alle PlugIns verwenden dieses Interface. Fertig.
      Die Anwendung lädt alle Dlls oder halt alle Klassen (also alle PlugIns), die das Interface implementieren.
      Dann hast Du eine List(Of IPlugInDings).
      "Luckily luh... luckily it wasn't poi-"
      -- Brady in Wonderland, 23. Februar 2015, 1:56
      Desktop Pinner | ApplicationSettings | OnUtils
      Der Sinn und Zweck von den Interfaces ist, diese nicht jedes mal umzuschreiben, da sonst alle Plugins nicht mehr gehen.
      Das Interface stellt allgemeine Methoden zur Kommunikation zwischen Programm und Plugin zur Verfügung.

      Beispiel: Matheplugins.

      Das Programm sendet zwei zahlen an das Plugin und erhält eine zurück

      VB.NET-Quellcode

      1. Public Interface iBerechnung
      2. ReadOnly Property Name as string
      3. Function Berechne(Byval a as Double, ByVal b as Double) as Double
      4. End Interface


      Und jedes plugin implementiert dieses Interface.

      VB.NET-Quellcode

      1. Public Class Addiere
      2. Implements iBerechnung
      3. Public Function Berechne(a As Double, b As Double) As Double Implements iBerechnung.Berechne
      4. Return a + b
      5. End Function
      6. Public ReadOnly Property Name As String Implements iBerechnung.Name
      7. Get
      8. Return "addiere"
      9. End Get
      10. End Property
      11. End Class
      12. Public Class Dividiere
      13. Implements iBerechnung
      14. Public Function Berechne(a As Double, b As Double) As Double Implements iBerechnung.Berechne
      15. Return a / b
      16. End Function
      17. Public ReadOnly Property Name As String Implements iBerechnung.Name
      18. Get
      19. Return "dividiere"
      20. End Get
      21. End Property
      22. End Class


      Rufe ich nun das Plugin Addiere auf, wird addiert. Rufe ich dividiere auf wird dividiert.
      SWYgeW91IGNhbiByZWFkIHRoaXMsIHlvdSdyZSBhIGdlZWsgOkQ=

      Weil einfach, einfach zu einfach ist! :D
      Aber nehmen wir mal an, ich habe ein Interface erstellt und dies gibt nur Integer/Doubles von Mathematikaufgaben aus. Aber nach der Fertigstellung will ich gerne noch eine Datumfunktion einbauen. Dann müsste ich doch das Interface wieder umbauen, oder nicht ?
      Hallo DerHans117,

      genau, und alle Programmteile die dein Interface implementieren neu kompilieren.

      Alleine das Interface austauschen reicht nicht.
      Deswegen ist es sehr wichtig, sich vorher gründlich Gedanken zu machen.

      Gruss

      mikeb69

      mikeb69 schrieb:

      genau

      Das Interface muss man nur anpassen, wenn man es anpassen muss ...
      Wenn man vorher weiß, dass sich sehr oft was ändern kann, dann macht man es halt von vornherein (zumindest teilweise) "generisch".

      Public Class GenericResult
      Public Result As Object
      Public ResultType As Type
      End Class

      Public Function Foo(functionname As String, ParamArray args() As Object) As GenericResult
      Ich hab alles nach dem Tutorial gemacht. Warum bekomme ich dann soviele Fehler?
      Ich glaub, ich bin echt zu blöd für alles :(
      Habe alle Verweise, etc. hinzugefügt. Aber es kommen trotzdem diese Errors...
      Bilder
      • Plugin.PNG

        306,29 kB, 1.911×1.069, 181 mal angesehen
      Nun ja, das finde ich aber irgendwie blöd, denn ich wollte ein Programm schreiben, mit dem man so alles mögliche machen kann. Heißt Aufgaben rechnen oder eine kleine Zahlenspiele. Nun weiß ich ja nicht, was mir später alles noch einfallen wird. Gibt es noch eine andere Möglichkeit, oder ist dies die Einzigste ?