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:
pluginPath
, myInterfaceAssembly
, das bereits geladen ist, oder Ich mache eindeutig nichts richtig. Ich habe es versucht:
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))
. AssemblyResolve
-Handler an this.appDomain
anhängen. Ich habe die gleiche Ausnahme wie in (1), und das manuelle Laden hilft nicht. this.appDomain
first. Das funktioniert nicht, aber ich bezweifle, dass mein Code korrekt ist: 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%Ich habe einen meiner Lösungsversuche erneut versucht:
Erstellen eines Objekts mit
this.appDomain.CreateInstanceAndUnwrap
, das von MarshalByRefObject mit einerLoadAssembly
-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 ichthis.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:
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.
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.
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%