Laden...

Assembly mittels Reflection laden

Erstellt von Golo Roden vor 18 Jahren Letzter Beitrag vor 18 Jahren 4.051 Views
Golo Roden Themenstarter:in
4.207 Beiträge seit 2003
vor 18 Jahren
Assembly mittels Reflection laden

Hallo,

ich versuche, eine Assembly mittels Reflection zur Laufzeit nachzuladen.

System.Reflection.Assembly.Load("Core.dll");

funktioniert nicht, da ich keinen starken Namen bereitstelle. Die Methode LoadWithPartialName ist in .NET 2.0 aber obsolet, was also tun?

Viele Grüße,

der Eisbär

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

S
8.746 Beiträge seit 2005
vor 18 Jahren

Load() will den Assembly-Namen, LoadFrom() den Filenamen.

Golo Roden Themenstarter:in
4.207 Beiträge seit 2003
vor 18 Jahren

Okay ... manchmal sieht man den Wald vor lauter Bäumen nicht.

Nun noch eine letzte Frage dazu - ich möchte nun ein Objekt einer Klasse aus dieser Assembly instanziieren, und dort eine bestimmte Methode aufrufen.

Mein Code sieht erst mal folgendermaßen aus:

Assembly coreAssembly = Assembly.LoadFrom("Core.dll");
object core = coreAssembly.CreateInstance("Core.Core");
core.Run();

Bis zu Zeile zwei klappt auch alles, nur gibt es natürlich keine Run-Methode auf dem Datentyp object ... kann mir jemand einen Tipp geben, wie ich an dieses Thema überhaupt herangehe?

Danke,

Golo

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

N
4.644 Beiträge seit 2004
vor 18 Jahren

Du musst den Rückgabewert noch casten, dann hast Du Deinen Type ( wenn alles gut geht 😉 ).

4.221 Beiträge seit 2005
vor 18 Jahren

Wobei um den Type zu casten muss er ja bekannt sein... ergo muss das Assembly referenziert sein....

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

N
4.644 Beiträge seit 2004
vor 18 Jahren

Ich Vollid..., hast natürlich Recht.
Dann kannste evtl. über Interfaces gehen, weiß ja nicht was Du machen willst.

Golo Roden Themenstarter:in
4.207 Beiträge seit 2003
vor 18 Jahren

Noodles' Idee war auch meine, nur tja .... wie mache ich den Typ bekannt, OHNE die DLL zu referenzieren?

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

4.221 Beiträge seit 2005
vor 18 Jahren

Die Idee mit dem Cast macht nur Sinn wenn z.B: ein implementiertes Interface .... oder die BaseClass des Objektes direkt referenziert ist (z.B: Plugin-Konzept)

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

N
4.644 Beiträge seit 2004
vor 18 Jahren

Ich sage mal, Microkernel. Such mal hier, dass hatten wir schon mehrmals.

6.862 Beiträge seit 2003
vor 18 Jahren

Bei meiner Anwendung mach ichs auch über Interfaces. Du estellst dir eine Klassenbibliothek mit den Interfaces. Die Typen in deiner nachzuladenen Bibliothek müssen jetzt dieses Interface implementieren. Nun kannst du in deiner Anwendung die KLassenbibliothek mit den Interfaces direkt refenrenzieren und deine anderen Klassenbiliothek nachladen und dann den Typ casten und dann kannst die Interfacefunktionen ja benutzen um mit dem Objekt zu arbeiten ohne die Klasse des Objektes kennen zu müssen.

Baka wa shinanakya naoranai.

Mein XING Profil.

S
8.746 Beiträge seit 2005
vor 18 Jahren

Definiere ein Interface, welche von der PlugIn-Klasse implementiert wird. Das Interface (nur das!) in eine eigene DLL packen und sowohl von Aufrufer, als auch vom PlugIn referenzieren. Ist der Name des Typen bekannst (z.B. PlugIn-Konfig-XML-File), dann direkt das Obejkt erzeugen und auf das Interfaces casten.

Alternativ kannst du auch alle Typen des PlugIns via Reflection abiterieren und prüfen, ob sie das Interface implementieren, dann weiter wie oben (Problem: Was ist wenn mehrere Klassen das Interface implementieren?).

In meinen Augen noch besser ist der Einsatz von Factory-Objekten/Interfaces im PlugIn. Man holt zunächst eine Factory aus dem Plugin, welches dann die weiteren Objekte (wieder nur via Interfaces zugegriffen) erzeugt. Das entspricht dann in etwa der Erzeugung via CreateInstance mit Parametern (der Activator ist ja eine Abstract Factory-Implementierung), nur findet hier schon die Typrüfung zur Compile-Zeit statt und nicht erst zu Laufzeit (wegen object[]).

_
416 Beiträge seit 2005
vor 18 Jahren

Hallo,

ich fand den MSDN Mag - Artikel recht intressant zu dem Thema. Hatte leider bisher noch nicht die Chance Spring.Net mal auszuprobieren.

cu, tb

Golo Roden Themenstarter:in
4.207 Beiträge seit 2003
vor 18 Jahren

Hallo,

so, eine erste Lösung habe ich nun - wie unter http://www.des-eisbaeren-blog.de/Default.aspx?Guid=d618811a-52fc-4b20-a599-fe370e957286 beschrieben.

Any comments?

Viele Grüße,

der Eisbär

PS: Ja, ich weiß, dass da Kommentare fehlen ^^

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

_
416 Beiträge seit 2005
vor 18 Jahren

Hallo,

ja ich hätte ne kleine Anmerkung. Ich weiß nicht ob ich grad aufm Schlauch stehe, aber was würde passieren wenn man das ganze ohne Reflection löst? Die dll heißt immer gleich. Die Klasse heißt immer gleich. Ist .Net wirklich so intelligent den unterschied zu erkennen wenn dort auf einmal eine andere DLL liegt als vorher? (Von Strong-Names mal abgesehen).

Denn das ist doch imho das gleiche Prinzip wie mit herkömmlichen DLLs. Ändert man nur eine davon, tauscht man diese einfach aus. Und alles funktioniert bestens.

Falls ich den Kernpunkt deines Artikels überlesen habe, mögest du mirs verzeihen.

cu, tb

Golo Roden Themenstarter:in
4.207 Beiträge seit 2003
vor 18 Jahren

Hallo,

Du hast natürlich recht, solange die DLL und die Klasse eh immer gleich heißen, hält sich der Sinn in Grenzen ... ich habe gestern noch einiges weiter entwickelt, und das ganze per XML-Datei dynamisch steuerbar gestaltet, und auch gleich noch eine Komponenten-Factory mit dazu gebastelt, die alledings noch ausgebaut werden soll, zum Beispiel um Singleton-Funktionalität.

Den Anfang habe ich nun aber geschafft (danke hier deshalb noch mal an alle, die mir Tipps gegeben haben), der weitere Code wird noch folgen 😉.

Viele Grüße,

Golo

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

6.862 Beiträge seit 2003
vor 18 Jahren

Das Spiel kann man ja noch beliebig weiter treiben. Mein Programm arbeitet ähnlich, nur das ich halt alle meine nachgeladenen Dll's in ne extra AppDomain lade, dort ShadowCopy aktiviert habe, und mir nen FileSystemWatcher drauf gelegt habe der mir Änderungen verfolgt an den Dll's. Nun kann ich wenn die Anwendung läuft einfach neue Versionen ins Plugin Verzeichnis bei mir kopieren, der lädt die neu, und beim nächsten Benutzen einer Funktion wird die neue Dll benutzt. Und das beste: der Anwender bekommt gar nichts mit 🙂 Das ganze Assembly konzept in .Net ist schon recht clever find ich.

Baka wa shinanakya naoranai.

Mein XING Profil.

Golo Roden Themenstarter:in
4.207 Beiträge seit 2003
vor 18 Jahren

*gg* .... die Idee hat was 😉

Ist das privater Code von Dir, den Du bereit wärst, weiterzugeben? Würde da gerne mal ein bisschen drin stöbern, einfach, um auch bissle was dabei zu lernen.

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

Golo Roden Themenstarter:in
4.207 Beiträge seit 2003
vor 18 Jahren

So, es gibt ein kleines Update - siehe http://www.des-eisbaeren-blog.de ... Komponenten werden nun aus eienr XML-Datei geladen und das ganze funktioniert nicht nur mit der Application-DLL, sondern mit beliebigen Komponenten 🙂

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

6.862 Beiträge seit 2003
vor 18 Jahren

Hab grad deinen Blog gelesen 😉 brauchst du das Beispiel noch? Also so wie ich es momentan verwende kann ichs dir eh leider nicht überlassen, aber könnte dir ne kleine "Technologiedemo" zeigen wo ich das in den Anfängen mal selber ausprobiert habe wie das funktioniert.

Gruß Talla

Baka wa shinanakya naoranai.

Mein XING Profil.

Golo Roden Themenstarter:in
4.207 Beiträge seit 2003
vor 18 Jahren

🙂

Also, ich denke schon, dass es mir helfen würde, zu sehen, wie Du daran gegangen bist. Und so eine Technologiedemo klingt doch schon mal recht gut 🙂.

Von dem her, wenn Du mir da was zeigen kannst, sehr gerne 🙂

Wissensvermittler und Technologieberater
für .NET, Codequalität und agile Methoden

www.goloroden.de
www.des-eisbaeren-blog.de

M
329 Beiträge seit 2004
vor 18 Jahren

Original von talla
Hab grad deinen Blog gelesen 😉 brauchst du das Beispiel noch? Also so wie ich es momentan verwende kann ichs dir eh leider nicht überlassen, aber könnte dir ne kleine "Technologiedemo" zeigen wo ich das in den Anfängen mal selber ausprobiert habe wie das funktioniert.

Gruß Talla

Hallo Talla, ist das Angebot noch Aktuell? Ich würde gerne mal reinschauen! Habe mich den ganzen Tag mit AppDomains und Setups herumgeschlagen, aber irgendwie komme ich auf keinen grünen Zweig 🙁

M
329 Beiträge seit 2004
vor 18 Jahren

Ich möchte mein Problem ein wenig ausführlicher beschreiben:

AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
setup.PrivateBinPath = "Plugin";
setup.ShadowCopyFiles = "true";

AppDomain app = AppDomain.CreateDomain("PluginDomain", AppDomain.CurrentDomain.Evidence, setup);

ArrayList assemblies = new ArrayList(app.GetAssemblies());
ArrayList plugins = new ArrayList();
foreach(Assembly asm in assemblies) {
	plugins.AddRange(GetPlugin(asm));
}
foreach(IPlugin p in plugins)
	Console.WriteLine("Plugin: " + p.Name);

setup.ApplicationBase ist das Verzeichnis in dem ich die Anwendung startete. Dort habe ich einen Unterordner "Plugin" in welchem ich eine Assembly habe. Doch die ArrayList assemblies hat nur eine Assembly drin, die mscorlib.dll! Warum? Ich blicke nicht durch...
Hoffe ihr könnt mir helfen 🙂

LG Michi