Quelles sont les meilleures pratiques d'utilisation des attributs d'assemblage?

163

J'ai une solution avec plusieurs projets. J'essaie d'optimiser les fichiers AssemblyInfo.cs en liant un fichier d'informations d'assemblage à l'échelle de la solution. Quelles sont les meilleures pratiques pour y parvenir? Quels attributs doivent figurer dans le fichier à l'échelle de la solution et lesquels sont spécifiques au projet / assemblage?


Edit: Si vous êtes intéressé, il y a une question de suivi Quelles sont les différences entre AssemblyVersion, AssemblyFileVersion et AssemblyInformationalVersion?

Jakub Šturc
la source

Réponses:

207

Nous utilisons un fichier global appelé GlobalAssemblyInfo.cs et un fichier local appelé AssemblyInfo.cs. Le fichier global contient les attributs suivants:

 [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")]

Le fichier AssemblyInfo.cs local contient les attributs suivants:

 [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")]

Vous pouvez ajouter GlobalAssemblyInfo.cs à l'aide de la procédure suivante:

  • Sélectionnez Ajouter / Élément existant ... dans le menu contextuel du projet
  • Sélectionnez GlobalAssemblyInfo.cs
  • Développez le bouton d'ajout en cliquant sur cette petite flèche vers le bas à droite
  • Sélectionnez "Ajouter en tant que lien" dans la liste déroulante des boutons
JRoppert
la source
quel est le but de conserver les anciens fichiers AssemblyInfo.cs? Lorsque j'automatise mon tampon de version de build dans GlobalAssemblyInfo.cs, comment cela met-il à jour le (s) fichier (s) AssemblyInfo.cs que j'ai dans ma solution?
D3vtr0n
3
@Devtron Les fichiers AssemblyInfo individuels doivent fournir des informations uniques à l'assembly dans lequel ils résident (par exemple, le titre, la description et la culture, comme dans l'exemple ci-dessus). Les entrées courantes, telles que le nom du produit et les informations de version doivent être supprimées (et entraîneront une erreur du compilateur si elles sont dupliquées). Idéalement, les fichiers AssemblyInfo ne seront pas mis à jour par le processus de génération.
David Keaveny
1
Le AssemblyCultureAttributemérite une meilleure explication. Il est préférable que l'attribut soit complètement absent (sauf s'il s'agit d'un assemblage satellite). Lorsque vous utilisez des assemblys satellites à grande échelle, il se peut que vous ayez besoin de trois, et non de deux niveaux de fichiers d'informations d'assemblage (global, assemblage principal et assemblage satellite qui spécifie uniquement la culture dans ce cas).
Jirka Hanika
20

Dans mon cas, nous construisons un produit pour lequel nous avons une solution Visual Studio, avec divers composants dans leurs propres projets. Les attributs communs disparaissent. Dans la solution, il y a environ 35 projets et une information d'assemblage commune (CommonAssemblyInfo.cs), qui a les attributs suivants:

[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")]

Les autres attributs tels que AssemblyTitle, AssemblyVersion, etc., nous fournissons sur une base par assemblage. Lors de la création d'un assembly, AssemblyInfo.cs et CommonAssemblyInfo.cs sont intégrés à chaque assembly. Cela nous donne le meilleur des deux mondes où vous voudrez peut-être avoir des attributs communs pour tous les projets et des valeurs spécifiques pour certains autres.

J'espère que cela pourra aider.

Krishna
la source
avez-vous plus de 35 entrées dans votre configuration de construction pour gérer cela? Cela semble plutôt redondant. Que faire si vous ajoutez 2 ou 3 nouveaux projets, est-ce que cela interrompt votre build jusqu'à ce que vous les ajoutiez à la tâche de gestion des versions?
D3vtr0n
1
@ D3vtr0n, pourquoi une «configuration de construction» (qu'entendez-vous par là) aurait-elle besoin de tant d'entrées? Je suppose que ce fichier est inclus dans chaque .csproj via <Compile Include="$(MSBuildThisFileDirectory)..\Common\CommonAssemblyInfo.cs"/>, une directive MSBuild qui peut même être dans un Common.targetsfichier partagé . Réutilisation du code Yay.
binki
15

La solution présentée par @JRoppert est presque la même que ce que je fais. La seule différence est que j'ai mis les lignes suivantes dans le fichier AssemblyInfo.cs local car elles peuvent varier avec chaque assembly:

#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)]

J'utilise également (généralement) une information d'assemblage commune par solution, en supposant qu'une solution est une seule ligne de produits / produit libérable. Le fichier d'informations d'assemblage commun contient également:

[assembly: AssemblyInformationalVersion("0.9.2.0")]

Ce qui définira la valeur "ProductVersion" affichée par l'Explorateur Windows.

Scott Dorman
la source
8

MSBuild Community Tasks contient une tâche personnalisée appelée AssemblyInfo que vous pouvez utiliser pour générer votre assemblyinfo.cs. Cela nécessite une petite édition manuelle de vos fichiers csproj à utiliser, mais cela en vaut la peine.

jlew
la source
6

À mon avis, utiliser un GlobalAssemblyInfo.cs est plus problématique qu'il n'en vaut la peine, car vous devez modifier chaque fichier de projet et n'oubliez pas de modifier chaque nouveau projet, alors que vous obtenez un AssemblyInfo.cs par défaut.

Pour les changements de valeurs globales (c'est-à-dire la société, le produit, etc.), les changements sont généralement si rares et simples à gérer que je ne pense pas que DRY devrait être une considération. Exécutez simplement le script MSBuild suivant (en fonction du pack d'extension MSBuild ) lorsque vous souhaitez modifier manuellement les valeurs de tous les projets de manière unique:

<?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
la source
3

Pour partager un fichier entre plusieurs projets, vous pouvez ajouter un fichier existant en tant que lien.

Pour ce faire, ajoutez un fichier existant et cliquez sur "Ajouter en tant que lien" dans le sélecteur de fichiers. (source: free.fr )Ajouter comme lien

Quant à ce qu'il faut mettre dans le fichier partagé, je suggérerais de mettre des éléments qui seraient partagés entre les assemblys. Des choses comme le droit d'auteur, la société, peut-être la version.

Cameron MacFarland
la source
1

L'utilisation d'un seul fichier AseemblyInfo.cs pour plusieurs projets n'est pas recommandée. Le fichier AssemblyInfo comprend des informations qui peuvent être pertinentes uniquement pour cet assembly spécifique. Les deux éléments d'information les plus évidents sont le AssemblyTitleet AssemblyVersion.

Une meilleure solution pourrait être d'utiliser un targetsfichier, qui est géré par MSBuild, afin d '«injecter» des attributs d'assembly à plusieurs projets.

SaguiItay
la source
et si vous avez plus de 20 projets? Cela m'oblige à conserver plus de 20 entrées dans ma configuration de construction, juste pour le contrôle de version. Cela semble vraiment nul. Et si j'ajoute 2 ou 3 nouveaux projets? Cela interrompra définitivement le processus de construction ... Des idées pour résoudre ce problème?
D3vtr0n
@ D3vtr0n Je pense que l'idée est de générer l'assemblage pertinent de manière dynamique et non de maintenir des configurations individuelles pour chaque projet. Community Tasks, je pense, gère ce cas.
Roman
1

Une chose que j'ai trouvée utile est de générer les éléments AssemblyVersion (etc.) en appliquant la substitution de jetons dans la phase de pré-construction.

J'utilise TortoiseSvn, et il est facile de l'utiliser SubWCRev.exepour transformer un modèle AssemblyInfo.wcreven AssemblyInfo.cs. La ligne appropriée dans le modèle peut ressembler à ceci:

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

Le troisième élément est alors le numéro de révision. J'utilise le quatrième élément pour vérifier que je n'ai pas oublié de valider des fichiers nouveaux ou modifiés (le quatrième élément est 00 si tout est OK).

Au fait, ajoutez AssemblyInfo.wcrevà votre contrôle de version et ignorez AssemblyInfo.cs si vous l'utilisez.

John Denniston
la source