2012-01-23 22 views
10

Ho un programma applicativo C#, chiamiamolo App.exe. Fa riferimento a una DLL denominata A.dll che a sua volta fa riferimento a un'altra DLL, ovvero B.dll. Tuttavia il modo in cui vengono citati è un po 'diverso. Nel codice di A.dll, ha fatto riferimento direttamente a B.dll (andando a Progetto> Riferimenti> Aggiungi B.dll). Tuttavia il mio App.exe ha il codice per caricare A.dll in fase di esecuzione utilizzando Assembly.Load() ecc.Riferimento a una DLL da un'altra DLL

Quindi per ricapitolare, App.exe ---- (caricamento in fase di esecuzione) ---> A.dll - - (riferimento diretto) ---> B.dll

Tutte e tre le cose (App.exe, A.dll e B.dll) risiedono nella stessa directory, ad esempio ExeDir. Ora quello che voglio fare è mettere A.dll e B.dll in una sottodirectory di ExeDir. Posso farlo utilizzando un file App.config che specifica il percorso di A.dll e chiede all'App.exe di caricare A.dll da quel percorso. Fin qui tutto bene.

Tuttavia il problema è che quando faccio questo, .NET mi dà un errore dicendo che non è possibile trovare B.dll che si trova nella stessa directory di A.dll. Se lo spostamento nella directory originale (la stessa directory di App.exe), quindi funziona correttamente. Il che significa che posso mettere A.dll in una sottodirectory, ma B.dll deve essere nella directory originale.

Esiste un modo per mantenere entrambe le DLL nella sottodirectory?

risposta

9

Aggiungi un elemento <probing> nel vostro app.config:

http://msdn.microsoft.com/en-us/library/823z9h8w.aspx

<configuration> 
    <runtime> 
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <probing privatePath="bin;bin2\subbin;bin3"/> 
     </assemblyBinding> 
    </runtime> 
</configuration> 
+0

Grazie per la risposta D Stanley. Ma sono un po 'in perdita qui. Puoi dirmi per favore che cosa dovrei fare esattamente qui? Solo per specificare questo elemento con il percorso dell'assembly? – Sach

+1

Sì relativo al tuo EXE. Ad esempio, nell'esempio MSDN il raccoglitore cercherà di default nella cartella 'BIN', ma cercherà anche la cartella' bin2', la cartella 'bin2 \ subbin' e la cartella' bin3'. Sostituisci 'bin; bin2 \ subbin; bin3' con la cartella (relativa all'EXE) in cui si trovano A.dll e B.dll. Notare che non è più necessario specificare il percorso di A.dll se è incluso nel file percorso di sondaggio. –

+0

Grazie Stanley, l'ho fatto funzionare! È stata colpa mia se non ho spiegato il mio problema completo qui. Il motivo per cui volevo le DLL in cartelle separate è che potrei avere diversi A.dll diversi (contenuto diverso) e ognuno di essi può fare riferimento a B.dll. Quindi volevo implementare un codice più sicuro, in modo tale che se A.dll diverso volesse riferirsi a B.dll, il quale potrebbe anche variare all'interno. Ma sembra che non possa essere fatto. Comunque, grazie!Hai risposto alla mia domanda originale. – Sach

5

È possibile risolvere manualmente l'assembly B.DLL fornendo un gestore di eventi all'evento AppDomain.AssemblyResolve dell'AppDomain corrente.

currentDomain.AssemblyResolve += ResolveLostAssemblies; 

quindi fornire un'implementazione di ResolveEventHandler:

private Assembly ResolveLostAssemblies(object sender, ResolveEventArgs args) 
{ 
    // Find the assembly referenced by args.Name, load it dynamically, and return it. 
} 

ho trovato che questo offre il massimo controllo su cui assemblee vengono caricati e quando. Funziona particolarmente bene nella situazione in cui l'applicazione è inseribile e ciascun plug-in risiede nella propria sottodirectory di una cartella "plugins" (che non è necessariamente la directory dell'applicazione). Tecnicamente, l'assembly non deve nemmeno essere un file fisico utilizzando questo metodo. Sebbene il metodo di D Stanley sia generalmente considerato più standard.

+0

Grazie Babcock! Ho avuto modo di lavorare con il metodo di Stanley. – Sach

Problemi correlati