![]() |
Klassenbiliothek (DLL) dynamisch Laden ?
Hallo zusammen,
ich schreibe etwas "artfremd", aber ich möchte gerne eine Kleinigkeit in .NET - genauer VB.NET - realisieren. Da ich bis jetzt kein gutes .NET Forum gefunden habe, schreibe ich hier - bitte nicht steinigen :angel: :angel: Also - ich habe eine Klassenbibliothek, die mit .NET kompiliert ist. Diese möchte ich gerne dynamisch aus einer anderen .NET Anwedung laden. "Statisch" funktioniert dies bereits, die DLL ist unter "Verweise" eingebunden und im Source entsprechend
Code:
aufgerufen. Wie gesagt - klappt alles.
Imports MyBaseClass
Hintergrund ist, daß ich nach Start der Anwendung die Existenz der DLL prüfen möchte (im gleichen Verzeichnis wie die Anwendung) um dann entsprechend darauf zu reagieren. Kann mir jemand einen Tip geben ? mfg Sebastian |
Re: Klassenbiliothek (DLL) dynamisch Laden ?
Hi,
ich glaube zwar nicht, dass es direkt was mit der API zu tun hat (hier solltest Du denke ich um das Verschieben durch einen Moderator bitten), aber Steine habe ich auch keine bei. Versuch es mal damit:
Code:
Obj musst Du natürlich noch entsprechend casten, da Du hier nur ein Object bekommst, aber grob sollte es (ungetestet, bin kein VB.netler) in der Richtung funktionieren.
assem = System.Reflection.Assembly.Load(....)
obj = assem.CreateInstance("<Klassentyp>") Gruß Der Unwissende |
Re: Klassenbiliothek (DLL) dynamisch Laden ?
Hallo,
Zitat:
Du hast mich auf alle Fälle schonmal auf die Fährte gesetzt. Ich komme jetzt aber partout nicht weiter :gruebel: :gruebel: :gruebel: Folgende Klassenbibliothek:
Code:
Ich habe mir jetzt gedacht, ich mache eine Konsolenanwendung, in der ich "einfach" nur die "Add" Funktion aufrufe:
Imports System
Namespace MyAssembly Public Class Maths Public Function Add(ByVal numberOne As Integer, ByVal numberTwo As Integer) Return numberOne + numberTwo End Function End Class End Namespace
Code:
Bis zu Dim t2 As MemberInfo() funktioniert auch alles. Die Fehlermeldung "typeSingle ist leer ?!" kommt NICHT.
Imports System
Imports System.Reflection Module Module1 Sub Main() Dim asm As Assembly = Assembly.LoadFrom("<Pfad>\MyAssembly.dll") Console.WriteLine("Types des Klassenbiliothek:") Dim typeArray As Type() typeArray = asm.GetTypes() Dim MonType As Type For Each MonType In typeArray Console.WriteLine("Type : " + MonType.Name) Next ' *** Jetzte Speziell für Type "Maths" abrufen Dim typeSingle As Type typeSingle = asm.GetType("Maths") If (typeSingle Is System.DBNull.Value) Then Console.WriteLine("typeSingle ist leer ?!") End If Dim t2 As MemberInfo() = typeSingle.GetMembers() ' Hier kommt immer der Fehler :-( End Sub End Module In der besagten Zeile bricht der Compiler mit "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt." ab. Das kann doch nur eine Banalität sein :gruebel: - aber ich komm nicht drauf. Probiert (wie ich "probieren" beim programmieren hasse) habe ich auch schon die typeSingle Zuweisung wie folgt zu ändern:
Code:
oder
typeSingle = asm.GetType("MyAssembly.Maths")
Code:
Gleiche Meldung. Entwicklungsumgebung ist VS2005.
typeSingle = asm.GetType("MyAssembly")
Achso: In der Ausgabe von "Console.WriteLine("Type : " + MonType.Name)" ist "Maths" enthalten. Zweifel langsam an mir selbst, das kann doch nicht so wild sein ?! :wall: Grüße, Sebastian |
Re: Klassenbiliothek (DLL) dynamisch Laden ?
Obwohl du VB benutzt, will ich mal trotzdem was dazu schreiben[1].
Ich werde es in C# schreiben, sollte aber nachvollziehbar sein. Man nehme 2 Assemblies. Eine nennen wir einfach mal PluginRtl, die andere PluginLib. In die PluginRtl packen wir ein Interface, welches durch die eigentliche Klasse im eigentlichen Plugin implementiert wird. Warum erkläre ich später. Die erste Assembly enthält nur das hier:
Code:
Die zweite Assembly setzt eine Referenz auf die erste und implementiert das Interface:
namespace PluginRtl
{ public interface IMathDings { int Add(int left, int right); } }
Code:
So nun noch schnell eine kleine Anwendung erzeugt, die wiederum die erste Assembly referenziert:
namespace PluginLib
{ public sealed class MathDings : IMathDings { public int Add(int left, int right) { return left + right; } } }
Code:
class Program
{ static void Main() { Assembly plugin = Assembly.LoadFile("PluginLib.dll"); Type mathDingsType = plugin.GetType("PluginRtl.MathDings"); if(typeof(IMathDings).IsAssignableForm(mathDingsType)) { IMathDings instance = Activator.CreateInstance(mathDingsType) as IMathDings; int result = instance.Add(1, 2); } } } Ist aber alles uncompiliert aus den Fingern gesaugt. Kleinere Ecken können also drin, aber es sollte trotzdem die Herangehensweise klar machen. Das Interface in einer eigene Assembly hat den Grund, dass man so eine Stelle hat, gegen die man kompilieren kann, aber trotzdem noch die Implementierung wechseln kann. [1] Vielleicht wirst du ja gezwungen und kannst nix dafür... |
Re: Klassenbiliothek (DLL) dynamisch Laden ?
Hallo,
erstmal vielen Dank für deine superschnelle Antwort. Zitat:
Ich habs leider nicht hinbekommen, ich dreh langsam durch... :shock: :shock: :-) Also - Klassenbibliothek mit folgenden Inhalt erstellt:
Code:
Hoffe, daß das alles korrekt ist. DLL wird ohne Fehler erstellt.
Namespace PluginRtl
Public Interface IMathDings Function Add(ByVal left As Integer, ByVal right As Integer) As Integer End Interface End Namespace Namespace PluginLib Public Class MathDings Implements PluginRtl.IMathDings Public Function Add(ByVal left As Integer, ByVal right As Integer) As Integer Implements PluginRtl.IMathDings.Add Return left + right End Function End Class End Namespace Jetzt gibt es wieder Probleme im Hauptprogramm - zunächst habe ich die typeof-Passage noch nicht umgesetzt. Da es nur eine If-Bedingung ist, habe ich das erstmal vernachlässigt. Das CreateInstance schlägt fehlt (wobei mir im übrigen die korrekte Syntax unter VB.NET nicht klar ist). Schliesslich habe ich es soweit reduziert:
Code:
Müsste das nicht eigentlich zumindest sauber abgearbeitet werden (auch wenn ich mit der Instanz nix anstellen kann, weil das Ergebniss von .CreateInstance nicht in einer Variable gespeichert wird) ? Es kommt nämlich die Meldung "Der Wert darf nicht NULL sein." bei .CreateInstance (die Meldung in meinem zweiten Post ist ja ähnlich).
Imports System.Reflection
Module Module1 Sub Main() Dim plugin As Assembly = Assembly.LoadFrom("<Pfad>\PluginLib.dll") Dim mathDingsType As Type = plugin.GetType("PluginRtl.MathDings") Activator.CreateInstance(mathDingsType) End Sub End Module Nochmal etwas grundsätzliches: Wo liegt denn eigentlich der praktische Unterschied, ob ich mit CreateInstance - wie aus deinem Beispiel - oder ohne - wie aus meinem zweiten Posting - arbeite ? Vielen Dank für Eure Geduld. Sebastian |
Re: Klassenbiliothek (DLL) dynamisch Laden ?
Zitat:
Die Klasse heißt PluginLib.MathDings, nicht PluginRtl.MathDings. Und immer schön dran denken: Die Interfaces/Klassen , die du in Anwendung und PlugIns benutzen willst, müssen in eine getrennte Assembly gepackt werden. Diese kann dann von Anwendung und Plugins benutzt werden. |
Re: Klassenbiliothek (DLL) dynamisch Laden ?
Hallo,
so ich habe mich recht weit "durchgebissen". Ich habe anfangs etwas (nach wie vor) an "GetType" gehangen, bis ich den .Fullname angegeben habe (passiert auch nur ein mal :wall: ) Zitat:
Code:
aufrufe, dann bekomme ich immer die Meldung "Das Objekt des Typs ... kann nicht in Typ ... (bei der zweiten Anweisung) umgewandelt werden.
Dim obj As Object = Activator.CreateInstance(MathClassType)
Dim iType As MyAssembly.IMyAssemblyNS.IMathClass = CType(obj, MyAssembly.IMyAssemblyNS.IMathClass) Ich würde mir gerne die DLL für das Interface sparen und "einbetten". Aber das wiederspricht ja eigentlich dem Sinn, oder ? Wenn ich das richtig verstanden habe, dann brauche ich kein Interface schreiben, wenn es sich um eine Assembly handelt, die zwar dynamisch nachgeladen, aber nicht austauschbar sein soll ? Dann würde ich die Funktionen der Klasse direkt ohne Interface ansprechen ? Alles nicht so einfach :-) Aber ich bin fast am Ziel. lg Sebastian |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz