2009-10-20 35 views
14

Digamos que tenemos una aplicación que consta de un ejecutable y 5 bibliotecas. Regularmente, todos estos estarán en un directorio y las bibliotecas se cargarán desde allí.C#: directorio de montaje personalizado

¿Es posible que pueda tener, por ejemplo, algunas de las bibliotecas en un directorio llamado Lib, y el resto en una llamada Lib2? De modo que el directorio de la aplicación solo contuviera el ejecutable y los otros ensamblajes estarían contenidos en varios directorios lógicos.

¿Cómo puedo hacer esto? Y me gustaría saber cómo hacer la carga de los ensamblajes, pero también cómo hacer que la construcción de la aplicación coloque los ensamblajes en el directorio correcto.

+0

Sí, se puede, por la respuesta de DotNetWill. Pero hay poco que ganar y puede encontrarse con muchos problemas de mantenimiento. –

Respuesta

30

Puede agregar rutas de búsqueda adicionales a su app.config que se ve para cargar ensamblajes. Por ejemplo

<runtime> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
    <probing privatePath="lib;thirdParty" /> 
    </assemblyBinding> 
</runtime> 

Puede ver más detalles here.

+0

Fantástico. Si quisiera más rutas, ¿agregaría otra etiqueta '', o agregaría otra '' con otra etiqueta ''? – Svish

+0

Además, ¿hay alguna forma de agregar esta ruta en tiempo de ejecución? Por ejemplo, si se creó utilizando algún tipo de variables de entorno u otras cosas. – Svish

+0

@ Svish # 2: Vea mi respuesta. – SLaks

2

Para copiar automáticamente los ensamblajes a la carpeta en la que desea que estén, puede establecer Copy Local como verdadero para todas las referencias y realizar un paso posterior a la compilación para moverlos a subdirectorios.

Alternativamente, podría configurar Copy Local a falso, y añadir los archivos DLL que se hace referencia como archivos en el proyecto en los subdirectorios apropiados, y establecer Build Action copiar al directorio de salida (Esto conservará subdirectorios)

El más flexible La forma de hacer que el tiempo de ejecución los encuentre es manejar el evento AppDomain.AssemblyResolve y cargar manualmente el ensamblado usando Assembly.LoadFile. Necesitará una forma para que su código sepa qué ensamblajes están en qué directorios.

+0

Esa cosa AssemblyResolve podría ser muy útil. Realmente no sabía acerca de eso. En cuanto a las cosas de construcción, ¿cuál dirías que es la solución más limpia para eso? Creo que ambos parecen un poco desordenados, pero realmente no he probado ninguno de ellos, así que realmente no tengo ni idea: p – Svish

+0

Si está utilizando referencias en tiempo de ejecución, copie a la ayuda local. es decir, si está utilizando desarrollos de interfaz, los módulos de complemento solo están disponibles en tiempo de ejecución y las referencias de tiempo de diseño no funcionarán en este contexto – Krishna

0

En su comentario, menciona la adición de rutas de acceso y ubicaciones en el tiempo de ejecución. Sí, puede, pero debe usar Assembly.Load() y posiblemente reflexión.

11

Si desea gestionar manualmente dónde conseguir ensambla a partir de, tiene dos posibilidades:

  1. controlar el evento AppDomain.AssemblyResolve (tal como se describe por SLaks). Aquí está el fragmento de código:

    static void Main(string[] args) 
    { 
        ... 
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); 
        ... 
    } 
    
    static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
    { 
        string assembliesDir = "your_directory"; 
        Assembly asm = Assembly.LoadFrom(Path.Combine(assembliesDir, args.Name + ".dll")); 
        return asm; 
    } 
    
  2. crear un dominio con su propia configuración (mediante el establecimiento de ApplicationBase o PrivateBinPath propiedades del objeto AppDomainSetup).

Así que si quieres seguir trabajando en el dominio actual que tienen que utilizar el método 1.

+0

¡gracias! me acabas de salvar, buscabas en Google una solución como esa, pero no encontré nada en las respuestas a otras preguntas. Esto hizo mi día :) – SwissCoder

+0

Estoy tratando de cargar un ensamblaje usando Assembly.Load que no está en GAC, que falla y se desencadena el evento AssemblyResolve, donde estoy usando LoadFrom para cargarlo desde una ruta. Ahora este conjunto se cargará en contexto de carga, entonces ¿Utiliza ahora imágenes Ngen 'ed? Gracias por cualquier ayuda – paritosh

Cuestiones relacionadas