2011-02-10 12 views
11

Tengo un sistema que usa MEF para cargar piezas. Cada una de estas partes depende de una biblioteca central. Cuando construyo el proyecto, agrego un número de versión de los archivos .dll como este:MEF Dependencias y control de versiones

  • part1-1.0.0.0.dll
  • part2-1.0.0.0.dll

Además, hay una aplicación que realiza la composición de MEF. También usa la biblioteca central. Descubrí que puedo implementar las DLL de "partes" y la composición funciona bien porque la aplicación ya ha cargado la biblioteca principal en la que confían las piezas. Así que mi sistema de archivos es como la siguiente:

  • /parts/part1-v1.dll
  • /parts/part2-v1.dll
  • compositor-V1.exe
  • núcleo V1.exe

El problema que tengo es cómo manejar las versiones del núcleo y las piezas. Supongamos que hago una actualización del núcleo y una de las partes. Luego, despliego los cambios. Así que ahora mi sistema de archivos podría ser algo como:

  • /parts/part1-v1.dll
  • /parts/part1-v2.dll
  • /parts/part2-v1.dll
  • compositor -v1.exe
  • núcleo v1.dll
  • núcleo v2.dll

¿Cómo puedo estar seguro de que part1-v1.dll utiliza núcleo v1.dll y part1-v2.d ll utiliza core-v2.dll? Necesito todas las versiones de las piezas que se cargarán y el uso de la versión adecuada del núcleo.

Las clases de piezas tienen el siguiente aspecto:

[Export(typeof(IPart))] 
public class Part1 
{ 
    public string GetSomethingFromCore() 
    { 
     return Core.GetSomethingFromCore(); 
    } 
} 

[Export(typeof(IPart))] 
public class Part2 
{ 
    public string GetSomethingFromCore() 
    { 
     return Core.GetSomethingFromCore(); 
    } 
} 

Respuesta

5

no strong naming ¿Toma el cuidado de su problema? Si un ensamblado está construido contra una fuerte dependencia nombrada, entonces usted sabe que solo aceptará la misma dependencia exacta hasta el último byte.

Alternativamente, si los nombres fuertes son demasiado restrictivos, podría poner números de versión en los nombres de los tipos. Por ejemplo:

[Export(typeof(IPart))] 
public class Part1v1 
{ 
    private readonly ICorev1 core; 

    [ImportingConstructor] 
    public Part1v1(ICorev1 core) 
    { 
     this.core = core; 
    } 
} 

[Export(typeof(IPart))] 
public class Part1v2 
{ 
    private readonly ICorev2 core; 

    [ImportingConstructor] 
    public Part1v2(ICorev2 core) 
    { 
     this.core = core; 
    } 
} 
+3

Volvería a este enfoque. Observe cómo Wim ha abstraído la funcionalidad 'Core' de las interfaces, esto es particularmente importante porque en el ejemplo dado de Lance, parece hacer referencia a 'Core' estáticamente, Part1 y Part2 estarían haciendo referencia a diferentes singleton estáticos, lo que normalmente no sería el comportamiento esperado. Al abstraer la funcionalidad de las interfaces, los argumentos 'core' pueden ser singleton _instances_, el mismo objeto, que publica la funcionalidad a través de dos versiones diferentes de la interfaz (ICorev1 e ICorev2). – Adam

+0

Eche un vistazo a todos los ensamblados de interoperabilidad de Microsoft Office y observe cómo tienen v8, v9, v10 dlls, etc. (con la versión en el espacio de nombres). Cada nueva versión _does_not_ redefine la funcionalidad de la última, pero simplemente _añade_ a la misma. Por lo tanto, desde el punto de vista de mantenimiento, su aplicación 'núcleo' sería (con el tiempo) algo como esto (pseudocódigo): clase Núcleo interno: ICorev1, ICorev2 { ICorev1.GetSomethingFromCore() {} ICorev2.GetSomethingFromCore2 () {} } – Adam

1

Usted necesita darle a su conjunto de núcleo todas sus partes strong names, entonces van a requerir una coincidencia exacta cuando se cargan los ensamblados de referencia. Esto también significa que tendrá que implementar múltiples copias de su ensamblaje central. Es decir. en lugar de

  • /parts/part1-v1.dll
  • /parts/part1-v2.dll
  • /parts/part2-v1.dll
  • compositor-V1.exe
  • núcleo -v1.dll
  • núcleo v2.dll

, dispondrá de:

  • /parts/1-1/part1-v1.dll
  • /piezas/1-1/núcleo-v1 .dll
  • /parts/1-2/part1-v2.dll
  • /parts/1-2/core-v2.dll
  • /parts/2-1/part2-v1.dll
  • /parts/2-1/core-v1.dll
  • compositor-V1.exe
  • núcleo v1.dll
  • núcleo v2.dll

La forma en que lo he hecho en el pasado, es solo para almacenar cada parte en una carpeta separada junto con todas las dependencias que necesita. Incluso si son (actualmente) la misma versión que en la aplicación. De modo que cuando su aplicación se traslada a core-v2, todas las partes que dependen de core-v1 todavía la tendrán.

Cuestiones relacionadas