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
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"
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
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
Natürlich is dynamic fehleranfällig.
Besser wäre da ein Plugin-System alá MEF.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
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
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.