2009-02-20 11 views
6

Sto provando a caricare alcuni moduli tramite l'aggancio negli eventi AppDomain.AssemblyResolve e AppDomain.ReflectionOnlyAssemblyResolve. Mentre ho fatto in modo che il primo funzionasse, fallisco miseramente su quest'ultimo. Ho bollito mio problema fino a questo piccolo programma:Perché ReflectionOnlyAssemblyResolve non viene eseguito quando si prova a Assembly.ReflectionOnlyLoad?

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; 
    } 
} 

L'esecuzione di questo programma non riesce con un FileNotFoundException quando si cerca di Assembly.ReflectionOnlyLoad, ma non chiama il gestore ReflectionOnlyAssemblyResolve. Sono piuttosto stordito lì.

Qualcuno ha un'idea di quale potrebbe essere la causa principale di questo e come farlo funzionare?

Grazie!

risposta

8

Sembrerebbe che l'evento ReflectionOnlyAssemblyResolve viene utilizzato solo per risolvere le dipendenze, non assiemi di primo livello, come indicato qui:

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

E qui:

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

+0

C'è un modo per intercettare un tentativo fallito di caricamento di sola riflessione di un assieme? – derabbink

+0

@derabbink Questa è una domanda a parte, immagino. – casperOne

0

Espansione sulla risposta di CasperOne.

Se si desidera intercettare gli eventi di Assembly Resolve diretti, è necessario collegarsi all'evento AppDomain.AssemblyResolve. Questo è un aggancio globale, anche se così da solo non si adatta al tuo scenario. Tuttavia, se l'applicazione è a thread singolo, è possibile un collegamento a breve termine per intercettare specifici eventi di risoluzione.

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 non viene attivato quando si utilizza ReflectionOnlyLoad(). Come ho capito, questo è di progettazione, per evitare il caricamento di assiemi che non sono "ricercati" dall'utente di ReflectionOnlyLoad(). Non sono ancora sicuro di essere completamente d'accordo con questo punto di vista. –