Was sind die Best Practices für die Verwendung von Baugruppenattributen?

163

Ich habe eine Lösung mit mehreren Projekten. Ich versuche, AssemblyInfo.cs-Dateien zu optimieren, indem ich eine lösungsweite Assembly-Info-Datei verknüpfe. Was sind die Best Practices dafür? Welche Attribute sollten in der lösungsweiten Datei enthalten sein und welche sind projekt- / montagespezifisch?


Bearbeiten: Wenn Sie interessiert sind, gibt es eine Folgefrage Was sind die Unterschiede zwischen AssemblyVersion, AssemblyFileVersion und AssemblyInformationalVersion?

Jakub Šturc
quelle

Antworten:

207

Wir verwenden eine globale Datei namens GlobalAssemblyInfo.cs und eine lokale Datei namens AssemblyInfo.cs. Die globale Datei enthält die folgenden Attribute:

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

Die lokale AssemblyInfo.cs enthält die folgenden Attribute:

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

Sie können die GlobalAssemblyInfo.cs wie folgt hinzufügen:

  • Wählen Sie im Kontextmenü des Projekts die Option Hinzufügen / Vorhandenes Element
  • Wählen Sie GlobalAssemblyInfo.cs aus
  • Erweitern Sie die Schaltfläche Hinzufügen, indem Sie auf den kleinen Abwärtspfeil rechts klicken
  • Wählen Sie "Als Link hinzufügen" in der Dropdown-Liste der Schaltflächen
JRoppert
quelle
Was ist der Zweck, um die alten AssemblyInfo.cs-Dateien zu behalten? Wie aktualisiere ich die AssemblyInfo.cs-Datei (en), die ich in meiner Lösung habe, wenn ich meinen Build-Versionsstempel in GlobalAssemblyInfo.cs automatisiere?
D3vtr0n
3
@Devtron Die einzelnen AssemblyInfo-Dateien sollten Informationen enthalten, die für die Assembly, in der sie sich befinden, eindeutig sind (z. B. Titel, Beschreibung und Kultur, wie im obigen Beispiel). Allgemeine Einträge wie der Produktname und die Versionsinformationen sollten entfernt werden (und verursachen einen Compilerfehler, wenn sie dupliziert werden). Im Idealfall werden die AssemblyInfo-Dateien durch den Erstellungsprozess nicht aktualisiert.
David Keaveny
1
Das AssemblyCultureAttributeverdient eine bessere Erklärung. Das Attribut sollte am besten vollständig fehlen (es sei denn, es handelt sich um eine Satellitenbaugruppe). Wenn Sie Satellitenbaugruppen in großem Maßstab verwenden, sind möglicherweise drei und nicht zwei Ebenen von Baugruppeninformationsdateien erforderlich (globale Baugruppe, Hauptbaugruppe und Satellitenbaugruppe, die in diesem Fall nur die Kultur angeben).
Jirka Hanika
20

In meinem Fall erstellen wir ein Produkt, für das wir eine Visual Studio-Lösung mit verschiedenen Komponenten in ihren eigenen Projekten haben. Die gemeinsamen Attribute gehen. Die Lösung enthält ungefähr 35 Projekte und eine allgemeine Assembly-Information (CommonAssemblyInfo.cs) mit den folgenden Attributen:

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

Die anderen Attribute wie AssemblyTitle, AssemblyVersion usw. werden pro Baugruppe bereitgestellt. Beim Erstellen einer Assembly werden sowohl AssemblyInfo.cs als auch CommonAssemblyInfo.cs in jede Assembly integriert. Dies gibt uns das Beste aus beiden Welten, in denen Sie möglicherweise einige gemeinsame Attribute für alle Projekte und spezifische Werte für einige andere haben möchten.

Hoffentlich hilft das.

Krishna
quelle
Haben Sie mehr als 35 Einträge in Ihrer Build-Konfiguration, um dies zu handhaben? Scheint eher überflüssig. Was passiert, wenn Sie 2 oder 3 neue Projekte hinzufügen, wird Ihr Build dadurch unterbrochen, bis Sie sie der Versionierungsaufgabe hinzufügen?
D3vtr0n
1
@ D3vtr0n, warum sollte eine "Build-Konfiguration" (was meinst du damit) so viele Einträge benötigen? Ich gehe davon aus, dass diese Datei in jeder .csproj-Datei enthalten ist <Compile Include="$(MSBuildThisFileDirectory)..\Common\CommonAssemblyInfo.cs"/>, einer MSBuild-Direktive, die sich möglicherweise sogar in einer gemeinsam genutzten Common.targetsDatei befindet. Yay Code Wiederverwendung.
Binki
15

Die von @JRoppert vorgestellte Lösung ist fast die gleiche wie meine. Der einzige Unterschied besteht darin, dass ich die folgenden Zeilen in die lokale AssemblyInfo.cs-Datei eingefügt habe, da sie mit jeder Assembly variieren können:

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

Ich verwende auch (im Allgemeinen) eine allgemeine Baugruppeninformation pro Lösung, mit der Annahme, dass eine Lösung eine einzelne Produktlinie / ein freisetzbares Produkt ist. Die allgemeine Assembly-Info-Datei enthält außerdem:

[assembly: AssemblyInformationalVersion("0.9.2.0")]

Dadurch wird der vom Windows Explorer angezeigte Wert für "ProductVersion" festgelegt.

Scott Dorman
quelle
8

MSBuild Community Tasks enthält eine benutzerdefinierte Aufgabe namens AssemblyInfo, mit der Sie Ihre Assemblyinfo.cs generieren können. Die Verwendung Ihrer csproj-Dateien erfordert eine kleine manuelle Bearbeitung, lohnt sich jedoch.

jlew
quelle
6

Meiner Meinung nach ist die Verwendung einer GlobalAssemblyInfo.cs mehr Mühe als es wert ist, da Sie jede Projektdatei ändern und daran denken müssen, jedes neue Projekt zu ändern, während Sie standardmäßig eine AssemblyInfo.cs erhalten.

Bei Änderungen an globalen Werten (z. B. Unternehmen, Produkt usw.) sind die Änderungen normalerweise so selten und einfach zu verwalten, dass ich nicht denke, dass DRY eine Überlegung sein sollte. Führen Sie einfach das folgende MSBuild-Skript aus (abhängig vom MSBuild Extension Pack ), wenn Sie die Werte in allen Projekten einmalig manuell ändern möchten:

<?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
quelle
3

Um eine Datei für mehrere Projekte freizugeben, können Sie eine vorhandene Datei als Link hinzufügen.

Fügen Sie dazu eine vorhandene Datei hinzu und klicken Sie in der Dateiauswahl auf "Als Link hinzufügen". (Quelle: free.fr )Als Link hinzufügen

Was in die freigegebene Datei eingefügt werden soll, würde ich vorschlagen, Dinge zu platzieren, die für mehrere Assemblys freigegeben werden. Dinge wie Urheberrecht, Firma, vielleicht Version.

Cameron MacFarland
quelle
1

Die Verwendung einer einzelnen AseemblyInfo.cs-Datei für mehrere Projekte wird nicht empfohlen. Die AssemblyInfo-Datei enthält Informationen, die möglicherweise nur für diese bestimmte Assembly relevant sind. Die zwei offensichtlichsten Informationen sind das AssemblyTitleund AssemblyVersion.

Eine bessere Lösung könnte darin bestehen, targetsDateien zu verwenden , die von MSBuild verarbeitet werden, um Assembly-Attribute in mehr als ein Projekt zu "injizieren".

SaguiItay
quelle
Was ist, wenn Sie mehr als 20 Projekte haben? Dafür muss ich mehr als 20 Einträge in meiner Build-Konfiguration verwalten, nur für die Versionierung. Das scheint wirklich lahm. Was ist, wenn ich 2 oder 3 neue Projekte hinzufüge? Das wird definitiv den Build-Prozess unterbrechen ... Irgendwelche Ideen, wie man das lösen kann?
D3vtr0n
@ D3vtr0n Ich denke, die Idee ist, die relevante Assembly dynamisch zu generieren und nicht für jedes Projekt individuelle Konfigurationen beizubehalten. Ich denke, Community-Aufgaben behandeln diesen Fall.
Roman
1

Eine Sache, die ich als nützlich empfunden habe, ist das Generieren der AssemblyVersion-Elemente (usw.) durch Anwenden der Tokensubstitution in der Vorbereitungsphase.

Ich benutze TortoiseSvn und es ist einfach, daraus SubWCRev.exeeine Vorlage AssemblyInfo.wcrevzu machen AssemblyInfo.cs. Die relevante Zeile in der Vorlage könnte ungefähr so ​​aussehen:

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

Das dritte Element ist dann die Revisionsnummer. Ich verwende das vierte Element, um zu überprüfen, ob ich vergessen habe, neue oder geänderte Dateien festzuschreiben (das vierte Element ist 00, wenn alles in Ordnung ist).

Fügen Sie übrigens AssemblyInfo.wcrevIhre Versionskontrolle hinzu und ignorieren AssemblyInfo.cs Sie sie , wenn Sie diese verwenden.

John Denniston
quelle