Code zur Laufzeit in eine Modul einladen; evtl. aus Datenbank

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 38 Antworten in diesem Thema. Der letzte Beitrag () ist von DrZwockel.

    ... werde ich versuchen ... Problem ist, dass es ein Office-Addin ist, das nur läuft, wenn es sich in (hier Excel) eingebunden hat.

    Ich versuche da mal eine Windowsanwendung draus zu machen und hier die Variablen "zuzuordnen".

    Ich melde mich ...


    Gruß vom Doc

    DrZwockel schrieb:

    das nur läuft, wenn es sich in (hier Excel) eingebunden hat.
    Ist schon klar.
    Ich meinte, dass Deine Datenstruktur da egal sein sollte, nimm also eine praktisch leere Tabelle mit einer Spalte oder so.
    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 RodFromGermany,

    so, jetzt habe ich das Musterbeispiel erstellt und dies in zweifacher Form.

    1. MEF als Boolean
    2. MEF als String

    Zur Erklärung. In der 1. MEF habe ich die Parameter drin, die alle übergeben werden müssen, das Plugin aber wie im Muster hier im Forum als Boolean deklariert ist. Das Beispiel funktioniert eingeschränkt. Der String wird noch korrekt zusammengesetzt, wenn er aber zurück gemeldet werden soll, wirft das Programm einen Fehler.

    In der 2. MEF habe ich ebenfalls alle Parameter drin, die alle übergeben werden müssen, das Plugin ist aber entgegen dem Muster hier im Beispiel als String deklariert. Das Beispiel läuft hier bis zum Laden des Plugin und wirft dann einen Fehler.

    Ziel sollte sein, dass der String korrekt erstellt wird und an die aufrufende Funktion zurückgeliefert wird, um ihn dann dort weiterverarbeiten zu können.


    Gruß vom Doc
    Dateien
    • MEF_Boolean.zip

      (129,15 kB, 94 mal heruntergeladen, zuletzt: )
    • MEF_String.zip

      (126,5 kB, 103 mal heruntergeladen, zuletzt: )
    @DrZwockel Zu viel Schrott. Sorry.
    • Machst Du Option Strict On.
    • Generiere Dir eine Projektmappe.
      Gehe ins MEF-Projekt und füge im Menüpunkt "Datei - Projekt hinzufügen" dsas Projekt "Plugin" der Projektmappe hinzu => da kannst Du gemeinsam debuggen.
    • Füge dieser Projektmappe ein neues DLL-Projekt hinzu: "Plugins", dort kommen alle Interface rein: IPlugin
    • Das Plugin-DLL-Projekt (nicht aber die Datei Plugin.DLL) fügst Du beiden Projekten als Verweis hinzu.
    • Entferne alle Verweise auf MEF aus der Plugin-DLL.
    • RodFromGermany schrieb:

      zippe es ohne Binaries

      heißt: ohne die Verzeichnisse obj, bin, .localhistory usw.
      das müllt nur den Server des Forums zu.
    Wenn Du das hast, geht vielleicht schon was besser.
    Melde Dich dann wieder.
    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!
    Ok, sorry ... werde ich machen.



    Hallo RodFromGermany,

    ich hoffe, ich habe es jetzt richtig hinbekommen ... ich habe es mal laufen lassen. Der Textstring (SQL-String) wird zusammengebaut, die Rücksendung des Strings schlägt aber mit einem Fehler fehl (Boolean).

    Die Änderung auf String anstatt Boolean habe ich in dieser Version nicht gemacht. WIe gesagt da hatte er ja schon die Fehler im Bereich der Stelle verbindung.ComposeParts(ME)

    VIelen Dank schon mal ...

    Gruß vom Doc

    Beiträge zusammengefügt. ~Thunderbolt
    Dateien
    • MEF_1.zip

      (33,85 kB, 92 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Thunderbolt“ ()

    @DrZwockel Du hast es noch nicht verstanden.
    Der Sinn eines Plugin-Systems besteht darin, dass solche DLLs dynamisch geladen werden, also im Hauptprogramm kein Verweis darauf gesetzt werden muss.
    Damit sich die zu ladende DLL und das ladende Hauptprogramm verstehen, wird ein Interface benötigt.
    Da ggf. mehrere unabhängige DLLs nebeneinander liegen können, wird die Interface-DLL separat erstellt und jedem der beteiligten Projekte als Verweis hinzugefügt.
    Insbesondere bedeutet dies, dass das Hauptprogramm starten kann, ohne dass eine einzige Plugin-DLL vorhanden sein muss!
    Nur die Interface-DLL muss da sein.
    Also:
    Füge Deiner Projektmappe ein DLL-Projekt hinzu, in das Du das Interface / alle Interfaces reinpackst.
    Lösch im Hauptprogramm alle Verweise auf Plugin-DLLs bzw. -Projekte und füge überall einen Verweis auf das Projekt der Interface-DLL hinzu.
    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 RodFrom Germany,

    ok, heißt also, dass das DLL Projekt mit dem Interface/der Interfaces dem Huaptprogramm zugeordnet ist (in Visual Studio).
    Das Hauptprogramm hat also somit keine Beziehung zur Plugin-DLL.

    Ich stelle mir das gerade so vor:

    Hauptprogramm <-------------> Interface DLL <----------------------> Plugin-DLL

    OK, aber das Problem mit der Rückgabe des Strings an das Hauptprogramm scheint damit aber nicht gelöst zu sein, da zwar in der DLL der String korrekt zusammengesetzt wird, aber nicht zurückgegeben werden kann (SQL-String).
    Mein Versuch dies mit String anstatt Boolean zu lösen, schlug ja bekanntlich ich Bereich verbindung.ComoseParts(Me) fehl. Hast Du dafür eine Erklärung?

    Ich werde das ganz jetzt am Wochenende mal zu Hause durchprobieren ... bin mal gespannt, ob ich das hin bekomme.

    Vielen Dank,

    Gruß vom Doc
    Ich hab die Problemstellung hoffentlich korrekt verstanden, den Rest der ganzen Diskussion habe ich auf jeden Fall nicht oder nur in Ansätzen verstanden. Daher fasse ich kurz zusammen:

    Der Nutzer gibt einen String oder mehrere ein, du durchsuchst Listen nach Objekten die vorhanden sind, frickelst daraus in SQL was zusammen und gibst das Abfrageergebnis zurück.

    Ich hoffe die Datenbank ist nicht Access. Ich habe etwas ähnliches neulich programmiert für grafische Auswertungen. Bei mir wählen die Nutzen aus einer (vorfilterterbaren) Liste alle Datenreihen aus, welche eingepflegt sind, wählen einen Zeitraum und ggf. Parameter aus, das wird an die Datenbank gesendet. In der Datenbank ist für jede Datenreihe ein Server, eine Datenbank, eine Datentabelle, eine Spalte mit der Zeit (bei mir die x-Achse), eine Spalte mit Werten (y-Achse) und noch einiges mehr hinterlegt. Handelt es sich bei der Quelle um was anderes als ne normale Tabelle, z.B. eine weitere gespeicherte Prozedur, andere Dienste usw. wird mit den vorhandenen Feldern nur anders verfahren. Als Rückgabe an die Software kommen nur immer zwei Spalten mit DateTime und Werten oder mit Werten und Werten. Um mehrere Datenreihen übereinander zu bringen spreche ich die Prozedur auf dem Server einfach mehrfach an.

    Das ganze hat natürlich die Schönheit, dass ich neue Datenreihen zur Laufzeit auf dem Server (oder mit einer Pflegemaske/einem Pflegeprogramm) hinzufügen kann und der Nutzer alles sofort hat, ohne dass ich eine neue Programmversion ausrollen muss. Bei über 10000 Datenreihen ne schicke Sache.

    Ist es das was dir vorschwebte?

    DrZwockel schrieb:

    Hast Du dafür eine Erklärung?
    Deswegen arbeiten wir zunächst asn der Struktur Deines Projekts, und wenn die in Ordnung ist, an der Lösung des Problems. ;)
    =============

    VB.NET-Quellcode

    1. Public Class Plugins
    2. <ImportMany(GetType(IPlugin))> Public Plugins As IPlugin()
    3. Public Sub LoadPlugins()
    4. Dim container = New CompositionContainer(New DirectoryCatalog("./Plugin"))
    5. container.ComposeParts(Me)
    6. End Sub
    7. End Class
    Dieser Teil gehört ins Hauptprogramm, denn dieses will ja die Plugins laden.
    Ich finde keine Implementierung Deines Interfaces, diese gehört eigentlich in die Plugin_1.dll.
    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!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()

    Guten Abend RodFromGermany,

    anbei der neue Code. Ich habe da etwas dran gebastelt, bis ich das so hin bekommen habe, wie Du es beschrieben hast.

    Der Test verlief positiv. Der SQL-String wird in der Messagebox angezeigt. Der Fehler tritt dann auf, wenn der String zurückgegeben werden soll. Aber das wirst Du dann selbst sehen.
    Bin mal gespannt, wie das Ergebnis aussieht, wenn wir fertig sind :)


    Gruß vom Doc
    Dateien
    • VB_PARA_Kurz.zip

      (412,98 kB, 75 mal heruntergeladen, zuletzt: )

    DrZwockel schrieb:

    Der Fehler tritt dann auf, wenn der String zurückgegeben werden soll.

    RodFromGermany schrieb:

    Machst Du Option Strict On.
    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 RodFromGermany,

    ich habe die drei Bestandteile alle auf Option Strict On gesetzt. Hierbei kam dann in MEF1_Plugin der Hinweis, dass das so nicht gehr und er hat mir eine Änderung angeboten, die ich angenommen habe.

    VB.NET-Quellcode

    1. '### hier kommt ein Fehler
    2. Return CBool(SQL_String.ToString)


    Dennoch meldet sich dann das Programm abschließend mit folgendem Fehler:
    System.InvalidCastException: "Ungültige Konvertierung von der Zeichenfolge SELECT YYYYMM, SUM(ANZAHL) AS PW in Typ Boolean."

    Ich bin etwas ratlos ...

    Gruß vom Doc
    OK. Er der Compiler sagt doch schon was nicht geht. Dein String kann nicht zu Boolean konvertiert werden.
    Warum soll denn ein Boolean returniert werden?
    Die deutsche Sprache ist Freeware, du kannst sie benutzen, ohne dafür zu bezahlen. Sie ist aber nicht Open Source, also darfst du sie nicht verändern, wie es dir gerade passt.
    Hallo MrTrebron,

    das ist ja auch eigentlich gar nicht die Grundidee gewesen ... sondern, dass grundsätzlich ein String zurückgeliefert werden soll. Beim Durchlaufen des Plugins wird der String zusammengesetzt.
    Dies funktioniert einwandfrei. Dann meldet sich Boolean, dass es funkioniert. Nur die Rückgabe des korrekten Strings funkioniert nicht ... und dieses Problem wollte ich gelöst haben (siehe Post #6).

    Gruß vom Doc

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „DrZwockel“ ()

    Wenn du den String aus der Funktion bekommen willst, wieso gibt die Funktion dann einen Boolean zurück und nicht einen String?

    Dazu muss natürlich das Interface angepasst werden.

    DrZwockel schrieb:

    Ich bin etwas ratlos ...
    Wie wird "Roulade mit Klößen" in Boolen konvertiert?
    Gar nicht, weil es nicht geht.Du musst der Funktion den Rückgabetyp String geben.
    Außerdem solltest Du alle 3 Projekte in eine Projektmappe packen, so etwa:
    MEF_1.zip
    Sieh Dir das PostBuild-Event der DLL an.
    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!
    Guten Abend RodFromGermany,

    eine schwere Geburt ist zu Ende gegangen. Eigentlich hatte ich mal eine Lösung, wo ich Boolean gegen String ausgetauscht hatte. Da hat er aber den Fehler im Bereich des conatiner.ComposeParts(Me) geworfen.

    Aber, so schaut es jetzt wohl aus, war sie nur so ähnlich, da deine Version einwandfrei läuft. Dafür ein ganz dickes Dankeschön. Aber auch ein ganz dickes Lob für Deine Geduld und das Du die Hilfe nicht mittendrin eingestellt hast.

    Ich habe in diesem Projekt nicht nur das MEF kennen und schätzen gelernt, sondern auch das PostBuildEreignis, das ich bis dato auch noch nicht kannte. Es erspart auf jeden Fall die Kopiererei ... Gibt es da auch eine Übersicht der Befehle, wie man den Zielordner definiert? Ich frage deshalb, da die DLL auf einen anderen Serverbereich soll ...

    Die Art, wie Du mich an die Lösung herangeführt hast, hat mir gefallen!

    @RodFromGermany
    Ich habe im Netz schon eine Anleitung gefunden, wie man den Kopierordner in eine andere Richtung lenkt 8o . Die schönen alten DOS Befehle...

    Vielen Dank,

    Gruß vom Doc

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „DrZwockel“ ()

    @DrZwockel Das PostBuild-Bereich ist nichts anderes als eine Batch-Datei.
    Projektbezogene Pfade werden als Makro dargestellt, so dass sie auch auf anderen Rechnern problemlos laufen.
    Betätige mal unten im Dialog den Button Makros.

    =====
    Bei mir sind im PostBuild-Ereignis die Pfade in Apostrophen eingeschlossen, weil da im Pfadnamen Leerzeichen vorkamen.
    Wenn in diesem Fall keine Apostrophen sind, funktioniert der Copy-Befehl nicht.
    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!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()

    Guten Morgen RodFrom Germany,

    vielen Dank für den Hinweis. Ich habe mir das gestern Abend im Netz noch zusammengesucht. Dort wurde das Verfahren der Batchdatei beschrieben. Ich habe dann in einem Test meinen Pfad zusammenbauen können. Diese Funktion ist ja wirklich sehr brauchbar :P . Die zusätzliche Kopiererei hat damit ein Ende.
    Ich glaube, dass das Studio noch so manche Hilfefunktion beinhaltet, die ich noch nicht kenne ... es scheint noch ein langer Weg zu sein ... ?(


    Gruß vom Doc

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „DrZwockel“ ()