Laden...

[gelöst] Assembly in AppDomain laden

Erstellt von Nuker vor 15 Jahren Letzter Beitrag vor 15 Jahren 1.635 Views
N
Nuker Themenstarter:in
12 Beiträge seit 2008
vor 15 Jahren
[gelöst] Assembly in AppDomain laden

Hi @ll!

Ich hoffe ihr könnt mir helfen. Ich hab folgendes Problem:

Ich will eine Art PlugIn System in meine Applikation einbauen. Um während der Laufzeit ganz easy die Plugins wieder entladen zu können und um meine Applikation zu schützen, sollen die Plugins in einer eigenen AppDomain geladen werden.

Nun mein Problem: Habe ich die AppDomain erstellt und will das Assembly in der AppDomain laden erhalte ich IMMER eine FileNotFoundException. Die Datei existiert allerdings und die Pfade sind alle richtig angegeben. Was mach ich falsch?

Mein Code sieht so ähnlich aus:

AssemblyName.GetAssemblyName(Path.GetFullPath(assemblyFilename));

m_AppDomain = AppDomain.CreateDomain(appDomainName);
m_AppDomain.Load(asseblyRef); // Hier kommt die Exception

Lade ich das Assembly wie folgt, funktioniert alles:

Assembly.LoadFrom(Path.GetFullPath(assemblyFilename));

Auch folgendes funktioniert:

AssemblyName.GetAssemblyName(Path.GetFullPath(assemblyFilename));

AppDomain.CurrentDomain..Load(asseblyRef);

Ich weiss es gibt noch die Möglichkeit über die Funktion "CreateInstance[...]" ein Assembly implizit zu laden, aber das ist nicht so angedacht. Denn hierfür wird ein bestimmter Typ benötigt, allerdings ist dieser zu diesem Zeitpunkt noch nicht vorhanden. Das Plugin System soll erst zur Laufzeit mittels Reflection alle öffentlichen Typen auslesen, was auch funktioniert (hab ich getestet) wenn ich das Plugin in der aktuellen AppDomain lade.

Ich hoffe ihr könnt mir helfen. Danke schon mal!!!

C YA @LL

NProcessMx: NProcess.org
NProcessMx SF: SF NProcess.org

3.971 Beiträge seit 2006
vor 15 Jahren

Warum benutzt du nicht

Assembly.LoadFrom(Path.GetFullPath(assemblyFilename));

?

Die Load Methode lädt eine Assembly nach dem vollqualifizierenden Namen (Name, Version, Kultur und Schlüssel)

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

N
Nuker Themenstarter:in
12 Beiträge seit 2008
vor 15 Jahren

Ich denke du meinst

Assembly.Load()

LoadFrom lädt wirklich ein Assembly aus einer Datei (Pfadangabe) in die aktuelle AppDomain

NProcessMx: NProcess.org
NProcessMx SF: SF NProcess.org

S
248 Beiträge seit 2008
vor 15 Jahren

Hallo Nuker,

ich habe dieses Problem ebenfalls schon gehabt.
Du kannst nur Assemblies laden, die im Ordner deiner Executable (oder einem Unterordner dessen) liegen.
Bevor du

m_AppDomain.Load(asseblyRef)

aufrufst, musst du den Unterordner (falls vorhanden) angeben:

AppDomain.CurrentDomain.AppendPrivatePath("Plugins\\Plugin1");

Danach kann die Assembly gefunden werden.

Spo

N
Nuker Themenstarter:in
12 Beiträge seit 2008
vor 15 Jahren

WUHUU!!!

Danke! Das war genau DAS was ich gebraucht habe!

Danke nochmal!

NProcessMx: NProcess.org
NProcessMx SF: SF NProcess.org

N
Nuker Themenstarter:in
12 Beiträge seit 2008
vor 15 Jahren

Hi!

Jetzt muss ich mich nochmal melden. Also das mit dem AppendPrivatePath hat wunderbar funktioniert, ABER: Das Assembly wird jetzt nicht nur in meiner manuell erstellten AppDomain geladen sondern auch in der CurrentDomain. Wenn ich jetzt ein Unload auf meine manuell erzeugte AppDomain ausführe, wird diese zwar korrekt entladen, aber das Assembly bleibt in der CurrentDomain geladen. Außerdem wird KEIN Event der manuell erzeugten AppDomain gefeuert (beim Laden eines Assembly, auffinden eines Assembly oder auch entladen der AppDomain). Mir scheint es als ob .Net lediglich die CurrentDomain kennt und auch nutzt und meine manuell erzeugte AppDomain vollkommen ignoriert. Darum wurde auch das Assembly nicht gefunden, ohne die AppendPrivatePath Angabe in der CurrentDomain, obwohl ich die manuelle AppDomain mit demselben BaseDirectory wie die CurrentDomain erstellt habe und in der MANUELLEN AppDomain das PrivateBinPath Attribut gesetzt habe. Dann hätte das Assembly, wie in der CurrentDomain, auch in der manuellen AppDomain gefunden werden sollen, allerdings hat .Net lediglich die CurrentDomain zum auffinden eines Assemblys verwenden.

Ich hoffe ihr könnt mir weiterhelfen.

NProcessMx: NProcess.org
NProcessMx SF: SF NProcess.org

3.971 Beiträge seit 2006
vor 15 Jahren

Lässt sich auch über die App.Config regeln (als alternative als Hart im Quellcode)
App.config Examples

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

N
Nuker Themenstarter:in
12 Beiträge seit 2008
vor 15 Jahren

Die App.config löst aber leider nicht mein Problem. Die AppDomains sollen dynamisch zur Laufzeit erstellt, verwaltet und wieder zerstört werden. Die Angaben oben mit den festen Verzeichnissen sind nur zu Testzwecken gewesen, eigentlich soll das alles dynamisch passieren.

NProcessMx: NProcess.org
NProcessMx SF: SF NProcess.org

1.665 Beiträge seit 2006
vor 15 Jahren

Soweit ich weiß, gehört ein bisschen mehr dazu, eine "echte" eigene AppDomain einzusetzen. Du brauchst einen AssemblyLoader, den du dann für deine AppDomain benutzt. Google mal nach den Stichwörtern, genaueres kann ich dir leider nicht sagen.

N
Nuker Themenstarter:in
12 Beiträge seit 2008
vor 15 Jahren

Danke für den Tip! Werds mir ansehen ... anscheinend gehts wirklich nicht ohne Proxy Objekte. Wenn's jemanden interessiert kann ich hier posten wie ich das Problem gelöst habe ...

C YA @LL

NProcessMx: NProcess.org
NProcessMx SF: SF NProcess.org

3.971 Beiträge seit 2006
vor 15 Jahren

Wenn's jemanden interessiert kann ich hier posten wie ich das Problem gelöst habe ...

Einfachen Posten. Entweder gibts jetzt bereits jemand der sich über eine Lösung freut oder dann zu einem späteren Zeitpunkt

Es gibt 3 Arten von Menschen, die die bis 3 zählen können und die, die es nicht können...

N
Nuker Themenstarter:in
12 Beiträge seit 2008
vor 15 Jahren

Hab hier ein sehr verständliches HowTo gefunden. Habs genau so umgesetzt und funktioniert so wie ich mir das vorgestellt habe.

Wer also selbst "autonome" AppDomains erstellen und verwenden will, dem lege ich diesen Artikel wärmstens ans Herz:

Anwendungsdomänen

Ist zwar schon ein bischen alt, ändert aber nix an der Lösung.

Also dann,
C YA @LL

NProcessMx: NProcess.org
NProcessMx SF: SF NProcess.org