¿Cuáles son las mejores prácticas para usar los atributos de ensamblaje?

163

Tengo una solución con múltiples proyectos. Estoy tratando de optimizar los archivos AssemblyInfo.cs vinculando un archivo de información de ensamblaje ancho de solución. ¿Cuáles son las mejores prácticas para hacer esto? ¿Qué atributos deben estar en el archivo de la solución y cuáles son específicos del proyecto / ensamblaje?


Editar: si está interesado, hay una pregunta de seguimiento ¿ Cuáles son las diferencias entre AssemblyVersion, AssemblyFileVersion y AssemblyInformationalVersion?

Jakub Šturc
fuente

Respuestas:

207

Estamos usando un archivo global llamado GlobalAssemblyInfo.cs y uno local llamado AssemblyInfo.cs. El archivo global contiene los siguientes atributos:

 [assembly: AssemblyProduct("Your Product Name")]

 [assembly: AssemblyCompany("Your Company")]
 [assembly: AssemblyCopyright("Copyright © 2008 ...")]
 [assembly: AssemblyTrademark("Your Trademark - if applicable")]

 #if DEBUG
 [assembly: AssemblyConfiguration("Debug")]
 #else
 [assembly: AssemblyConfiguration("Release")]
 #endif

 [assembly: AssemblyVersion("This is set by build process")]
 [assembly: AssemblyFileVersion("This is set by build process")]

El AssemblyInfo.cs local contiene los siguientes atributos:

 [assembly: AssemblyTitle("Your assembly title")]
 [assembly: AssemblyDescription("Your assembly description")]
 [assembly: AssemblyCulture("The culture - if not neutral")]

 [assembly: ComVisible(true/false)]

 // unique id per assembly
 [assembly: Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")]

Puede agregar GlobalAssemblyInfo.cs mediante el siguiente procedimiento:

  • Seleccione Agregar / Elemento existente ... en el menú contextual del proyecto
  • Seleccione GlobalAssemblyInfo.cs
  • Expanda el botón Agregar haciendo clic en esa pequeña flecha hacia abajo en la mano derecha
  • Seleccione "Agregar como enlace" en la lista desplegable de botones
JRoppert
fuente
¿Cuál es el propósito de mantener los viejos archivos AssemblyInfo.cs? Cuando automatizo mi sello de versión de compilación en GlobalAssemblyInfo.cs, ¿cómo actualiza eso los archivos AssemblyInfo.cs que tengo en mi solución?
D3vtr0n
3
@Devtron Los archivos de información de ensamblaje individuales deben proporcionar información exclusiva del ensamblaje en el que residen (por ejemplo, título, descripción y cultura, como en el ejemplo anterior). Deben eliminarse las entradas comunes, como el nombre del producto y la información de versiones (y provocarán un error del compilador si se duplican). Idealmente, los archivos AssemblyInfo no serán actualizados por el proceso de compilación.
David Keaveny
1
El AssemblyCultureAttributemerece una mejor explicación. El atributo debería estar completamente ausente por completo (a menos que se trate de un conjunto de satélite). Cuando se usan conjuntos satelitales a gran escala, uno puede necesitar tres, no dos niveles de archivos de información de conjunto (conjunto global, conjunto principal y conjunto satélite que solo especifica la cultura en este caso).
Jirka Hanika
20

En mi caso, estamos creando un producto para el que tenemos una solución de Visual Studio, con varios componentes en sus propios proyectos. Los atributos comunes van. En la solución, hay alrededor de 35 proyectos y una información de ensamblaje común (CommonAssemblyInfo.cs), que tiene los siguientes atributos:

[assembly: AssemblyCompany("Company")]
[assembly: AssemblyProduct("Product Name")]
[assembly: AssemblyCopyright("Copyright © 2007 Company")]
[assembly: AssemblyTrademark("Company")]

//This shows up as Product Version in Windows Explorer
//We make this the same for all files in a particular product version. And increment it globally for all projects.
//We then use this as the Product Version in installers as well (for example built using Wix).
[assembly: AssemblyInformationalVersion("0.9.2.0")]

Los otros atributos, como AssemblyTitle, AssemblyVersion, etc., los suministramos por ensamblaje. Al construir un ensamblaje, tanto AssemblyInfo.cs como CommonAssemblyInfo.cs se integran en cada ensamblaje. Esto nos brinda lo mejor de ambos mundos, donde es posible que desee tener algunos atributos comunes para todos los proyectos y valores específicos para otros.

Espero que ayude.

Krishna
fuente
¿Tiene más de 35 entradas en su configuración de compilación para manejar esto? Parece bastante redundante. ¿Qué sucede si agrega 2 o 3 proyectos nuevos, eso rompe su compilación hasta que los agregue a la tarea de Control de versiones?
D3vtr0n
1
@ D3vtr0n, ¿por qué una "configuración de compilación" (qué quiere decir con eso) necesita tantas entradas? Supongo que este archivo está incluido en cada archivo .csproj <Compile Include="$(MSBuildThisFileDirectory)..\Common\CommonAssemblyInfo.cs"/>, una directiva MSBuild que incluso puede estar en un Common.targetsarchivo compartido . Yay código de reutilización.
binki
15

La solución presentada por @JRoppert es casi la misma que yo. La única diferencia es que pongo las siguientes líneas en el archivo AssemblyInfo.cs local, ya que pueden variar con cada ensamblaje:

#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else
[assembly: AssemblyConfiguration("Release")]
#endif
[assembly: AssemblyVersion("This is set by build process")]
[assembly: AssemblyFileVersion("This is set by build process")]
[assembly: CLSCompliant(true)]

También (generalmente) utilizo una información de ensamblaje común por solución, con la suposición de que una solución es una sola línea de producto / producto liberable. El archivo de información de ensamblaje común también tiene:

[assembly: AssemblyInformationalVersion("0.9.2.0")]

Que establecerá el valor "ProductVersion" que muestra el Explorador de Windows.

Scott Dorman
fuente
8

MSBuild Community Tasks contiene una tarea personalizada llamada AssemblyInfo que puede usar para generar ensamblarinfo.cs. Requiere una pequeña edición manual de sus archivos csproj para usar, pero vale la pena.

jlew
fuente
6

En mi opinión, usar un GlobalAssemblyInfo.cs es más problemático de lo que vale, porque necesitas modificar cada archivo de proyecto y recordar modificar cada nuevo proyecto, mientras que obtienes un AssemblyInfo.cs por defecto.

Para los cambios en los valores globales (es decir, empresa, producto, etc.), los cambios suelen ser tan infrecuentes y fáciles de administrar que no creo que DRY deba ser una consideración. Simplemente ejecute el siguiente script de MSBuild (depende del paquete de extensión de MSBuild ) cuando desee cambiar manualmente los valores en todos los proyectos de manera única:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="UpdateAssemblyInfo" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <ItemGroup>
        <AllAssemblyInfoFiles Include="..\**\AssemblyInfo.cs" />
    </ItemGroup>

    <Import Project="MSBuild.ExtensionPack.tasks" />

  <Target Name="UpdateAssemblyInfo">
    <Message Text="%(AllAssemblyInfoFiles.FullPath)" />
    <MSBuild.ExtensionPack.Framework.AssemblyInfo 
        AssemblyInfoFiles="@(AllAssemblyInfoFiles)"
        AssemblyCompany="Company"
        AssemblyProduct="Product"
        AssemblyCopyright="Copyright"
        ... etc ...
        />
  </Target>

</Project>
Jack Ukleja
fuente
3

Para compartir un archivo entre múltiples proyectos, puede agregar un archivo existente como un enlace.

Para hacer esto, agregue un archivo existente y haga clic en "Agregar como enlace" en el selector de archivos. (fuente: free.fr )Agregar como enlace

En cuanto a qué poner en el archivo compartido, sugeriría poner cosas que se compartirían entre los ensamblados. Cosas como derechos de autor, compañía, tal vez versión.

Cameron MacFarland
fuente
1

No se recomienda usar un solo archivo AseemblyInfo.cs para múltiples proyectos. El archivo AssemblyInfo incluye información que puede ser relevante solo para ese ensamblado específico. Las dos piezas de información más obvias son el AssemblyTitley AssemblyVersion.

Una mejor solución podría ser usar un targetsarchivo, que es manejado por MSBuild, para "inyectar" atributos de ensamblaje en más de un proyecto.

SaguiItay
fuente
¿Qué pasa si tienes más de 20 proyectos? Eso requiere que mantenga más de 20 entradas en mi configuración de compilación, solo para el control de versiones. Eso parece realmente cojo. ¿Qué sucede si agrego 2 o 3 proyectos nuevos? Eso definitivamente romperá el proceso de construcción ... ¿Alguna idea de cómo solucionar eso?
D3vtr0n
@ D3vtr0n Creo que la idea es generar el ensamblaje de relevate dinámicamente y no mantener configuraciones individuales para cada proyecto. Community Tasks, creo, maneja ese caso.
Roman
1

Una cosa que he encontrado útil es generar los elementos AssemblyVersion (etc.) aplicando la sustitución de tokens en la fase previa a la compilación.

Yo uso TortoiseSVN, y es fácil de usar su SubWCRev.exea su vez una plantilla AssemblyInfo.wcreven AssemblyInfo.cs. La línea relevante en la plantilla podría verse así:

[assembly: AssemblyVersion("2.3.$WCREV$.$WCMODS?1:0$$WCUNVER?1:0$")]

El tercer elemento es entonces el número de revisión. Utilizo el cuarto elemento para verificar que no he olvidado enviar ningún archivo nuevo o modificado (el cuarto elemento es 00 si todo está bien).

Por cierto, agregue AssemblyInfo.wcreva su control de versiones e ignore AssemblyInfo.cs si usa esto.

John Denniston
fuente