AppDomain-Abhängigkeiten zwischen Verzeichnissen

8

Ich erstelle ein Plugin-System und ich erstelle eine AppDomain pro Plugin. Jedes Plugin hat ein eigenes Verzeichnis mit seinen Haupt-Assemblies und Referenzen. Die Haupt-Assemblys werden von meinem Plugin-Loader zusätzlich zu meinen Interface-Assemblys geladen (so dass das Plugin mit der Anwendung interagieren kann).

Erstellen der AppDomain:

%Vor%

Laden der Baugruppen:

%Vor%

Das Format von assemblyName ist der Dateiname der Assembly ohne ".dll".

Das Problem ist, dass AppDomain.Load(assemblyName) eine Ausnahme auslöst:

  

Datei oder Assembly konnte nicht geladen werden [[assemblyName]], Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null 'oder eine seiner Abhängigkeiten. Das System kann die angegebene Datei nicht finden.

Alle Abhängigkeiten von [[assemblyName]] sind:

  1. Innerhalb des Verzeichnisses pluginPath ,
  2. Das myInterfaceAssembly , das bereits geladen ist, oder
  3. In der GAC (z.B. mscorelib).

Ich mache eindeutig nichts richtig. Ich habe es versucht:

  1. Erstellen eines Objekts mit this.appDomain.CreateInstanceAndUnwrap , das von MarshalByRefObject mit einer LoadAssembly -Methode erbt, um die Assembly zu laden. Ich bekomme eine Ausnahme, die besagt, dass die aktuelle Assembly (mit der Proxy-Klasse) nicht geladen werden konnte (Datei nicht gefunden, wie oben), auch wenn ich manuell this.appDomain.Load(Assembly.GetExecutingAssembly().GetName(true)) .
  2. aufruft
  3. Einen AssemblyResolve -Handler an this.appDomain anhängen. Ich habe die gleiche Ausnahme wie in (1), und das manuelle Laden hilft nicht.
  4. Rekursives Laden von Assemblys durch Laden ihrer Abhängigkeiten in this.appDomain first. Das funktioniert nicht, aber ich bezweifle, dass mein Code korrekt ist:
%Vor%

Wie kann ich meine Plugin-Assembly mit ihren Abhängigkeiten in das Plugin-Verzeichnis laden und gleichzeitig einige Assemblies in das aktuelle Verzeichnis laden?

Hinweis: Die Assemblies, auf die sich ein Plugin möglicherweise (wahrscheinlich) bezieht, sind bereits in der aktuellen Domain geladen. Dies kann bei Bedarf auf verschiedene Domains verteilt werden (Leistungsvorteil? Einfachheit?).

Fusionsprotokoll:

%Vor%     
strager 24.12.2010, 14:31
quelle

3 Antworten

10

Ich habe einen meiner Lösungsversuche erneut versucht:

  

Erstellen eines Objekts mit this.appDomain.CreateInstanceAndUnwrap , das von MarshalByRefObject mit einer LoadAssembly -Methode erbt, um die Assembly zu laden. Ich bekomme eine Ausnahme, die besagt, dass die aktuelle Assembly (die die Proxy-Klasse enthält) nicht geladen werden konnte (Datei nicht gefunden, wie oben), selbst wenn ich this.appDomain.Load(Assembly.GetExecutingAssembly().GetName(true)) manuell anrufe.

Ich habe herausgefunden, dass CreateInstanceFromAndUnwrap den Pfad zu einer Assemblydatei akzeptieren kann, was die Dinge einfach macht:

%Vor%

Dies löst meine AppDomain-Erstellungsprobleme. (Jetzt um alles andere zum Laufen zu bringen!)

Danke für die Hilfe aller; Ich schätze Ihre Eingaben sehr.

    
strager 24.12.2010, 17:38
quelle
3

Ich glaube, dass die Ausnahme auftritt, wenn sie versucht, die Assembly in das Hauptverzeichnis AppDomain zu laden und nicht die Domäne, die Sie explizit erstellt haben. Dies ist ein Nebeneffekt der Verwendung von AppDomain.Load , was dazu führt, dass die Assembly in die aktuelle Domäne und die von Ihnen erstellte Domäne geladen wird. Da sich die Assembly nur im bin-Pfad (Plugin-Verzeichnis) der von Ihnen angelegten Domain befindet, erhalten Sie die Ausnahme.

Von MSDN im Zusammenhang mit AppDomain.Load :

  

Die Baugruppe wird in beide geladen   Domänen, weil Assembly nicht   abgeleitet von MarshalByRefObject und   daher der Rückgabewert der Last   Methode kann nicht gemarshallt werden. Stattdessen,   die Common Language Runtime versucht zu   Laden Sie die Baugruppe in den Aufrufer   Anwendungsdomäne.

    
João Angelo 24.12.2010 15:39
quelle
2

Ich hatte ein ähnliches Problem. Sie müssen die Methode zum Suchen der Baugruppen anpassen. Die Console.Debug-Anweisungen müssen möglicherweise geändert werden, um zu kompilieren, aber hier ist der allgemeine Kern:

%Vor%     
Andrew Stern 24.12.2010 17:01
quelle

Tags und Links