Laden...

Verwenden einer dynamisch geladenen .NET DLL

Erstellt von scrabbl vor 10 Jahren Letzter Beitrag vor 10 Jahren 1.682 Views
S
scrabbl Themenstarter:in
211 Beiträge seit 2010
vor 10 Jahren
Verwenden einer dynamisch geladenen .NET DLL

Hallo,

ich habe eine .NET DLL die ich nicht selber erstellt habe, kann da also weder reinschauen noch was daran ändern. Wenn ich sie normal über Referenzen einbinde geht da zum Beispiel folgendes:


IChannelConfig[] list = ChannelRegistry.getInstance().getChannelList();

Wobei IChannelConfig ein Interface und ChannelRegistry eine Klasse aus der DLL sind.
Das Ganze möchte ich jetzt dynamisch zur Laufzeit laden (da der Pfad auf den Zielsystemen variieren kann). Und da hänge ich im Moment etwas. Hab das in der Vergangenheit selten gemacht und wenn nur bei DLLs mit ganz einfachen Funktionen die nur irgendwas berrechnen und zurückgeben.


Assembly myAssembly = Assembly.LoadFile(dllPath);
Type myClassType = myAssembly.getType("com.mk.offcard.terminal.lite.ChannelRegistry");
object obj = FormatterServices.GetUninitializedObject(myClassType); //Activator.CreatInstance geht wegen des fehlenden Konstruktors wohl nicht
MethodInfo[] mInfos = myClassType.GetMethods();
object result = mInfos[0].Invoke(obj, null);

Soweit sogut, jetzt sollte result ja ein ChannelRegistry Objekt sein, nur komm ich jetzt nicht weiter, wie kann ich auf diesem Objekt weiterarbeiten ? In diesem Fall also getChannelList() aufrufen ? Mir ist nicht klar wie ich dieses Objekt jetzt weiter verarbeiten kann...

Grüße

P
660 Beiträge seit 2008
vor 10 Jahren

Hallo,

du kannst mit dynamic arbeiten

dynamic MyChannelConfig = Assembly.CreateInstance("ChannelConfig");
var Results = MyChannelConfig.getChannelList();

besser als mit Invoke-Methoden (Meiner meinung nach)

MfG
ProGamer*Der Sinn Des Lebens Ist Es, Den Sinn Des Lebens Zu Finden! *"Wenn Unrecht zu Recht wird dann wird Widerstand zur Pflicht." *"Ignorance simplifies ANY problem." *"Stoppt die Piraterie der Musikindustrie"

S
scrabbl Themenstarter:in
211 Beiträge seit 2010
vor 10 Jahren

Hallo,

danke für die Antwort.
dynamic war das gesuchte Stichwort, man lernt nie aus 👍


Assembly.CreateInstance(...);

Das geht bei mir leider nicht, da die ChannelRegistry keinen Konstruktor besitzt sondern das Objekt nur über getInstance() zu bekommen ist. Bei CerateInstance tritt eine Exception auf die mir eben dies mitteilt.

es hat aber gereicht in meinem Code oben in der letzten Zeile aus dem "object" ein "dynamic" zu machen und ich kann dann ganz normal auf dem Objekt arbeiten.

Grüße

S
scrabbl Themenstarter:in
211 Beiträge seit 2010
vor 10 Jahren

Noch ein Nachtrag bzw. eine Frage:

Kann es sein das diese Art der Verwendung von Assemblys ziemlich fehleranfällig ist ? Ich meine da bemerkt ja nichtmal der Compiler etwas. Ob es geht oder nicht merkt man ja letztendlich erst während der Ausführung.

Klar, getestet werden muss überall, aber gibt es auch fehlersicherer Möglichkeiten?

Grüße

16.835 Beiträge seit 2008
vor 10 Jahren

Natürlich is dynamic fehleranfällig.
Besser wäre da ein Plugin-System alá MEF.

49.485 Beiträge seit 2005
vor 10 Jahren

Hallo scrabbl,

wobei die meisten Plugin-Systeme darauf basieren, dass die zu verwendenden Klassen ein bestimmtes Interface implementieren, welches im Gegensatz zu den Plugins/Klassen statisch geladen wird und somit zur Compile-Zeit der Hostanwendung bekannt ist. Das geht aber nicht direkt, wenn du die DLLs nicht ändern kannst. Aber du könntest natürlich einen entsprechenden Wrapper für die DLL schreiben.

herbivore

849 Beiträge seit 2006
vor 10 Jahren

Hmm, also nur der Pfad der Assembly ist unbekannt? Was spricht dagegen bei Programmstart mit AssemblyResolve zu Arbeiten?

Dann kannst Du Sie zur Compile Zeit einfach Referenzieren und den Assembly Pfad z.b. in der AppConfig hinterlegen.