2009-02-20 4 views
6

Ich versuche, ein paar Module über das Einhängen in die AppDomain.AssemblyResolve und AppDomain.ReflectionOnlyAssemblyResolve Ereignisse zu laden. Während ich den ersteren zur Arbeit brachte, scheiterte ich kläglich an letzterem. Ich habe mein Problem eingekocht zu diesem kleinen Programm:Warum wird ReflectionOnlyAssemblyResolve nicht ausgeführt, wenn Assembly.ReflectionOnlyLoad versucht wird?

public static class AssemblyLoader 
{ 
    static void Main(string[] args) 
    { 
     AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += 
      ReflectionOnlyAssemblyResolve; 

     // fails with FileNotFoundException 
     Assembly.ReflectionOnlyLoad("Foo"); 
    } 

    public static Assembly ReflectionOnlyAssemblyResolve(object sender, 
     ResolveEventArgs args) 
    { 
     Trace.TraceInformation(
      "Failed resolving Assembly {0} for reflection", args.Name); 

     return null; 
    } 
} 

Das Ausführen dieses Programms mit einem FileNotFoundException schlägt fehl, wenn auf Assembly.ReflectionOnlyLoad versucht, aber es stellt nicht den ReflectionOnlyAssemblyResolve Handler. Ich bin dort ziemlich ratlos.

Hat jemand eine Idee, was die Ursache dafür sein könnte und wie man dies zur Arbeit bringt?

Danke!

Antwort

8

Es scheint, dass die ReflectionOnlyAssemblyResolve Ereignis nur Abhängigkeiten verwendet wird, zu lösen, nicht auf oberster Ebene Baugruppen, wie hier angegeben:

http://codeidol.com/csharp/net-framework/Assemblies,-Loading,-and-Deployment/Assembly-Loading/

Und hier:

http://blogs.msdn.com/junfeng/archive/2004/08/24/219691.aspx

+0

Gibt es eine Möglichkeit, einen fehlgeschlagenen Versuch, eine Baugruppe nur mit Reflektion zu laden, abzufangen? – derabbink

+0

@derabbink Das ist eine separate Frage, würde ich mir vorstellen. – casperOne

0

Ausbau auf casperOnes Antwort.

Wenn Sie direkte Assembly Resolve-Ereignisse abfangen möchten, müssen Sie das AppDomain.AssemblyResolve-Ereignis haken. Dies ist ein globaler Haken, so dass es alleine nicht zu Ihrem Szenario passt. Wenn Ihre Anwendung jedoch single threaded ist, können Sie eine kurzfristige Verbindung herstellen, um bestimmte Auflösungs-Ereignisse abzufangen.

static void LoadWithIntercept(string assemblyName) { 
    var domain = AppDomain.CurrentDomain; 
    domain.AssemblyResolve += MyInterceptMethod; 
    try { 
    Assembly.ReflectionOnlyLoad(assemblyName); 
    } finally { 
    domain.AssemblyResolve -= MyInterceptMethod; 
    } 
} 

private static Assembly MyInterceptMethod(object sender, ResolveEventArgs e) { 
// do custom code here 
} 
+0

AssemblyResolve wird nicht ausgelöst, wenn ReflectionOnlyLoad() verwendet wird. Nach meinem Verständnis ist dies beabsichtigt, um das Laden von Assemblys zu vermeiden, die vom Benutzer von ReflectionOnlyLoad() nicht "gewünscht" sind. Ich bin mir allerdings noch nicht sicher, ob ich diesem Standpunkt vollkommen zustimme. –