2009-05-14 6 views
17

Me gustaría crear una clase que compila en una sola DLL. Esta DLL agregaría funcionalidad a un producto existente.¿Es posible tener referencias DLL independientes de la versión en una clase?

Para que esto funcione, la clase personalizada hace referencia a las DLL contenidas en el producto subyacente. Estas referencias son necesarias para compilar.

Todo funciona bien aquí y la clase personalizada se compila. Puedo colocar la DLL producida en el producto y todo funciona bien.

Sin embargo, este producto tiene varias versiones (versiones menores, service packs). Me gustaría distribuir esta DLL a otros, pero me parece que la DLL debe coincidir con perfectamente la versión del producto. Si no hay un partido perfecto, entonces se produce el siguiente error:

No se pudo cargar el archivo o ensamblado 'Product.Web.UI, versión = 3.6.1920.2, Culture = neutral, PublicKeyToken = dfeaee0e3978ac79 'o una de sus dependencias. La definición del manifiesto del conjunto ubicado no coincide con la referencia del ensamblado. (Excepción de HRESULT: 0x80131040)

¿Cómo producir un DLL que no es exigente con la referencia de la versión?

Respuesta

4

Aún no tengo una respuesta a mi pregunta, pero usaré esta respuesta para registrar las migas de pan que encontré mientras buscaba una solución.

me encontré con una pregunta algo relacionado en StackOverflow:

Compile a version agnostic .DLL in .NET (Using Manifests?)

que no tengo la capacidad de modificar el producto subyacente sin embargo, así que la respuesta no funciona para mí.


Actualizado:

le envié un correo a alguien mucho más inteligente que yo, y aquí fue la respuesta:

Cuando hace referencia ensamblado con nombre, por Visual Studio por defecto añade referencia completa a la que se hace referencia montaje. Eso significa que incluye el nombre del ensamblado, la versión exacta, la cultura y el token de clave pública. Si alguna de esta información no coincide, se lanza la excepción descrita.

La eliminación de los nombres fuertes de nuestros ensamblajes simplemente no es una opción. No entraré en detalles por qué, pero puedes investigar un poco en MSDN.

Por lo tanto, tiene dos opciones para construir soluciones contra cada versión de los ensamblados a los que hace referencia.

  1. Podría hacer referencia parcial. Ver este artículo: http://msdn.microsoft.com/en-us/library/0a7zy9z5(VS.71).aspx.
  2. Puede declarar versiones compatibles con la redirección de enlaces en web.config. Ver este artículo: http://msdn.microsoft.com/en-us/library/433ysdt1.aspx.

En general se recomienda el segundo método porque: 1. No se puede utilizar de referencia parcial a asambleas en la caché de ensamblados global, es decir, de su control será la misma excepción si son ensamblados en la GAC. 2. Establece explícitamente versiones compatibles.

-1

En VisualStudio, ¿ha intentado hacer clic derecho en el ensamblaje al que se hace referencia (dll) y luego seleccionar las propiedades y configurar "requiere una versión específica" (más o menos)? Eso puede resolver su problema.

Andreas

+1

Sí, lo probé. Según entiendo, esta configuración solo se aplica en tiempo de compilación. Es decir, durante la compilación, el compilador no es exigente con la versión de la DLL que encuentra. Sin embargo, para la DLL resultante, esas referencias de DLL no específicas se convertirán en referencias de ensamblado fuertemente nombradas (completadas con el número de versión) en función de la DLL que se utilizó para compilar. –

7

Esta es una solución excelente. Resolvió un problema similar para mí.

Compile a version agnostic DLL in .NET

En caso de que vincular muere nunca, la clave está en controlar el evento AppDomain.CurrentDomain.AssemblyResolve como a continuación. El evento se desencadena cada vez que falla un enlace de ensamblaje, por lo que puede resolverlo usted mismo, solucionando conflictos de versión.

using System.Reflection; 

static Program() 
{ 
    AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs e) 
    { 
     AssemblyName requestedName = new AssemblyName(e.Name); 

     if (requestedName.Name == "Office11Wrapper") 
     { 
      // Put code here to load whatever version of the assembly you actually have 

      return Assembly.LoadFile("Office11Wrapper.DLL"); 
     } 
     else 
     { 
      return null; 
     } 
    } 
} 
Cuestiones relacionadas