6

En nuestra tienda, estamos utilizando Cruise Control & MSBuild para automatizar las compilaciones del producto como parte de la integración continua.Obtener InternalsVisibleTo para trabajar cuando el proceso de compilación firma el ensamblado con nombres fuertes?

Parte de la compilación consiste en firmar los ensamblajes para que tengan nombres seguros.

En nuestros archivos de proyecto cuando desarrollamos localmente, no especifica la firma, ya que esto es reemplazado por el script MSBuild.

Esto está muy bien hasta que decidí que me gustaría introducir pruebas unitarias que requieren que use el atributo InternalsVisibleTo. También comencé a usar una buena biblioteca de código abierto que tiene pruebas unitarias que también usan esta técnica.

Esto significa que, en mi máquina, puedo actualizar AssemblyInfo.cs utilizar la siguiente declaración:

[assembly: InternalsVisibleTo("MyProject.Tests.UnitTests")] 

y todo está bien.

Sin embargo, comprobar esto en las pausas de la construcción ya que la construcción de la máquina firma los montajes, sería necesario que la línea de ser actualizado para parecerse a esto en su lugar:

[assembly: InternalsVisibleTo("MyProject.Tests.UnitTests, 
      PublicKey="magic key here..)"] 

tengo casi decidido a no firmar las asambleas y llámalo un día. Sin embargo, "la firma de montajes es una buena práctica" (repetir este mantra 3 veces), y si estamos recibiendo ningún beneficio de hacer esto, no quiero a distancia él.

No instalamos en el GAC, no estamos especialmente preocupados por la manipulación, no tenemos que preocuparnos por los terceros que utilizan nuestras bibliotecas, actualizamos todos nuestros archivos a la vez cuando actualizamos la aplicación. El beneficio más identificable es alguien de apoyo no puede copiar alguna versión aleatoria de un ensamblado en la carpeta de tiempo de ejecución y tienen cosas parecen funcionar por un tiempo.

No quiero abrir la lata de trabajos involucrados con el cambio de alrededor de 100 archivos de proyecto manualmente para habilitar la firma. Asimismo, no quiero cortar las cosas marcando las cosas que deben ser internos como públicos, no quiero entrar en redirecciones vinculantes & que no quiero para eliminar las pruebas unitarias.

Me gustaría tener la facilidad de no tener nombres fuertes con todas las ventajas de tener nombres fuertes (si los hay), y no quiero crear mucho trabajo adicional para hacerlo. es mucho para preguntar?

Este post describe el problema y una solución bien, pero yo no soy mucho de un tipo script de MSBuild para tomar ventaja de ella:

http://social.msdn.microsoft.com/forums/en-US/msbuild/thread/02df643c-956a-48bd-ac01-4a1016d91032/

¿Cuál es la solución adecuada a este problema?

Cualquier entrada y punto de discusión son bienvenidos.

Respuesta

4

Usted puede parchear la información clave en los archivos fuente antes de compilar.

En el siguiente ejemplo se usa FileUpdate del MSBuild Community Tasks y una expresión regular (muy cruda) para aplicar la información de la clave en archivos C# AssemblyInfo.cs.

<ItemGroup> 
    <AssemblyInfoFiles Include="$(MSBuildProjectDirectory)**/AssemblyInfo.cs"/> 
</ItemGroup> 
<FileUpdate 
    Files="@(AssemblyInfoFiles)" 
    Regex='(\[assembly:\s*InternalsVisibleTo\(\"[\w.]*\")(\)\])' 
    ReplacementText='$1, PublicKey="$(StrongNamingPublicKey)"$2' /> 

Sin embargo, creo que la modificación de los proyectos para siempre de nombre seguro señal sería la solución más limpia para eliminar una diferencia más entre los entornos de desarrollo y desplegados, y podría ser fácilmente secuencias de comandos.

+0

Gracias Thomas, voy a probar esto y lo aceptaré como la respuesta una vez que lo haga funcionar. Hay algunos problemas para firmarlo con fuerza en todas partes, principalmente porque no estoy seguro de cómo guiar ese cambio y no quiero hacerlo manualmente. Nuestra secuencia de comandos de compilación existente, que fue escrita por alguien que conoce MSBuild mejor que yo, firma y voy a modificarla un poco en lugar de introducir un cambio importante. – Wes

+0

Nunca hice que esto funcione, pero lo marcaré como la respuesta. Lo que no funcionó es el ItemGroup llamado AssemblyInfoFiles ... siempre estaría vacío ... alguna idea de por qué? El patrón Incluir es básicamente lo que publicaste ... ¡Gracias! – Wes

+1

El ItemGroup anterior asume que los archivos AssemblyInfo.cs a parche se encuentran en un directorio debajo del script de compilación; el comodín '**' coincidirá con cualquier directorio que esté por debajo del actual. Consulte [Cómo seleccionar los archivos para compilar] (http://msdn.microsoft.com/en-us/library/ms171454.aspx) para obtener más información sobre la sintaxis de MSBuild include. –

5

Utilice la misma construcción que emplea para deshabilitar la firma de una compilación de desarrollador para definir un símbolo de compilación, por ej. DO_NOT_SIGN, a continuación, en su AssemblyInfo.cs, utilice esto:

#if DO_NOT_SIGN 
[assembly: InternalsVisibleTo("MyProject.Tests.UnitTests")] 
#else 
[assembly: InternalsVisibleTo("MyProject.Tests.UnitTests, PublicKey="magic key here..)"] 
#endif 

En mi opinión personal es más elegante que modificar el código fuente de la escritura de la estructura.

+0

Gracias por la respuesta skolima. Supongo que el problema de esta solución para mí es que ahora tengo que entrar manualmente en X número de archivos y crear esta construcción, sin embargo, muchas veces es necesario, yo u otros tenemos que recordar hacerlo en nuevos proyectos, y hay un poco de reproceso involucrado en el caso improbable de que la clave sea cambiada. Tiene el beneficio de ser visible y comprensible para cualquiera, y no es un misterio oculto en el script MSBuild, que no todos entienden muy bien. Creo que el programador perezoso en mí va a ir con el script de compilación ya que hay un marco para él en nuestros scripts. – Wes

Cuestiones relacionadas