2012-01-23 30 views
10

Tengo un programa de aplicación C#, llamémoslo App.exe. Hace referencia a una DLL llamada A.dll que a su vez hace referencia a otra DLL, concretamente, B.dll. Sin embargo, la forma en que se les hace referencia es un poco diferente. En el código de A.dll, ha hecho referencia directa a B.dll (yendo a Proyecto> Referencias> Agregar B.dll). Sin embargo, mi App.exe tiene código para cargar A.dll en tiempo de ejecución usando Assembly.Load() etc.Referencia a una DLL desde otra DLL

Recapitulando, App.exe ---- (carga en tiempo de ejecución) ---> A.dll - - (referencia directa) ---> B.dll

Las tres cosas (App.exe, A.dll y B.dll) residen en el mismo directorio, digamos ExeDir. Ahora lo que quiero hacer es colocar a A.dll y B.dll en un subdirectorio de ExeDir. Puedo hacer esto usando un archivo App.config que especifique la ruta de A.dll y solicite a App.exe que cargue A.dll desde esa ruta. Hasta aquí todo bien.

Sin embargo, el problema es que cuando hago esto, .NET me da un error al decir que no puede encontrar B.dll que está en el mismo directorio que A.dll. Si lo vuelvo a mover al directorio original (el mismo directorio que App.exe), entonces funciona bien. Lo que significa que puedo poner a A.dll en un subdirectorio, pero el B.dll necesita estar en el directorio original.

¿Hay alguna manera en que pueda mantener ambas DLL en el subdirectorio?

Respuesta

9

Añadir un elemento <probing> en su 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

Gracias por la respuesta D Stanley. Pero estoy un poco perdido aquí. ¿Puedes decirme qué se supone que debo hacer exactamente aquí? Solo para especificar este elemento con la ruta de ensamblaje? – Sach

+1

Sí, en relación con su EXE. Por ejemplo, en el ejemplo de MSDN, el archivador buscará en la carpeta 'BIN' de forma predeterminada, pero también buscará en la carpeta' bin2', en la carpeta 'bin2 \ subbin' y en la carpeta' bin3'. Reemplace 'bin; bin2 \ subbin; bin3' con la carpeta (relativa al EXE) en la que se encuentran A.dll y B.dll. Tenga en cuenta que ya no tiene que especificar la ruta a A.dll si está incluida en el sendero de sondeo –

+0

Gracias Stanley, ¡lo tengo para trabajar! Fue mi culpa, sin embargo, que no explique mi problema completo aquí. La razón por la que quería las DLL en carpetas separadas es que podría tener varios archivos A.dll diferentes (contenido diferente), y cada uno de ellos puede hacer referencia a B.dll. Así que quería implementar un código más seguro, de modo que si A.dll diferente quisiera referirse a B.dll, también pudiera variar dentro. Pero parece que no se puede hacer. Aún así, gracias!Usted respondió mi pregunta original. – Sach

5

Puede resolver manualmente el ensamblaje B.DLL proporcionando un controlador de eventos para el evento AppDomain.AssemblyResolve del AppDomain actual.

currentDomain.AssemblyResolve += ResolveLostAssemblies; 

a continuación, proporcionar una implementación de ResolveEventHandler:

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

he encontrado que esto proporciona un mayor control sobre las cuales se cargan asambleas y cuándo. Funciona especialmente bien en la situación en la que su aplicación es conectable y cada complemento vive en su propio subdirectorio de una carpeta de "complementos" (que no es necesariamente el directorio de la aplicación). Técnicamente, el ensamblaje ni siquiera tiene que ser un archivo físico utilizando este método. Aunque el método de D Stanley generalmente se considera más estándar.

+0

Gracias Babcock! Lo tengo que trabajar con el método de Stanley. – Sach

Cuestiones relacionadas