Jakie są najlepsze rozwiązania dotyczące używania atrybutów zestawu?

163

Mam rozwiązanie z wieloma projektami. Próbuję zoptymalizować pliki AssemblyInfo.cs, łącząc jeden plik informacji o zespole dla całego rozwiązania. Jakie są najlepsze praktyki w tym zakresie? Które atrybuty powinny znajdować się w pliku dla całego rozwiązania, a które są specyficzne dla projektu / zespołu?


Edycja: Jeśli jesteś zainteresowany, pojawia się pytanie uzupełniające. Jakie są różnice między AssemblyVersion, AssemblyFileVersion i AssemblyInformationalVersion?

Jakub Šturc
źródło

Odpowiedzi:

207

Używamy pliku globalnego o nazwie GlobalAssemblyInfo.cs i lokalnego o nazwie AssemblyInfo.cs. Plik globalny zawiera następujące atrybuty:

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

Lokalny plik AssemblyInfo.cs zawiera następujące atrybuty:

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

Możesz dodać GlobalAssemblyInfo.cs przy użyciu następującej procedury:

  • Wybierz Dodaj / istniejący element ... w menu kontekstowym projektu
  • Wybierz GlobalAssemblyInfo.cs
  • Rozwiń przycisk Add, klikając tę ​​małą strzałkę w dół po prawej stronie
  • Wybierz „Dodaj jako łącze” z rozwijanej listy przycisków
JRoppert
źródło
jaki jest cel przechowywania starego pliku (ów) AssemblyInfo.cs? Kiedy zautomatyzuję sygnaturę wersji kompilacji w GlobalAssemblyInfo.cs, w jaki sposób to zaktualizuje pliki AssemblyInfo.cs, które mam w rozwiązaniu?
D3vtr0n
3
@Devtron Poszczególne pliki AssemblyInfo powinny zawierać informacje unikalne dla zestawu, w którym się znajdują (np. Tytuł, opis i kultura, jak w powyższym przykładzie). Typowe wpisy, takie jak nazwa produktu i informacje o wersji, powinny zostać usunięte (i jeśli zostaną zduplikowane, spowoduje to błąd kompilatora). W idealnym przypadku pliki AssemblyInfo nie będą aktualizowane w procesie kompilacji.
David Keaveny
1
AssemblyCultureAttributeZasługuje na lepsze wyjaśnienie. Najlepiej, aby atrybut był całkowicie nieobecny (chyba że jest to zestaw satelitarny). Podczas korzystania z zestawów satelitów na dużą skalę, potrzebne mogą być trzy, a nie dwa poziomy plików informacyjnych zespołu (globalny, zespół główny i zespół satelitarny, który określa tylko kulturę w tym przypadku).
Jirka Hanika
20

W moim przypadku budujemy produkt, dla którego mamy rozwiązanie Visual Studio, z różnymi komponentami we własnych projektach. Idą wspólne atrybuty. W rozwiązaniu istnieje około 35 projektów i wspólne informacje o zestawie (CommonAssemblyInfo.cs), które mają następujące atrybuty:

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

Inne atrybuty, takie jak AssemblyTitle, AssemblyVersion itp., Dostarczamy na podstawie zestawu. Podczas budowania zespołu zarówno AssemblyInfo.cs, jak i CommonAssemblyInfo.cs są wbudowane w każdy zespół. Daje nam to to, co najlepsze z obu światów, w których możesz chcieć mieć pewne wspólne atrybuty dla wszystkich projektów i określone wartości dla innych.

Mam nadzieję, że to pomoże.

Kryszna
źródło
czy masz ponad 35 wpisów w konfiguracji kompilacji, aby to obsłużyć? Wydaje się raczej zbędne. Co jeśli dodasz 2 lub 3 nowe projekty, czy to zepsuje twoją kompilację, dopóki nie dodasz ich do zadania przechowywania wersji?
D3vtr0n
1
@ D3vtr0n, dlaczego „konfiguracja kompilacji” (co przez to rozumiesz) wymagałaby tak wielu wpisów? Zakładam, że ten plik jest zawarty w każdym pliku .csproj do <Compile Include="$(MSBuildThisFileDirectory)..\Common\CommonAssemblyInfo.cs"/>, w dyrektywie MSBuild, która może nawet znajdować się w Common.targetspliku udostępnionym . Ponowne wykorzystanie kodu Yay.
binki
15

Rozwiązanie przedstawione przez @JRoppert jest prawie takie samo jak to, co robię. Jedyną różnicą jest to, że umieściłem następujące wiersze w lokalnym pliku AssemblyInfo.cs, ponieważ mogą się one różnić w zależności od każdego zespołu:

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

Używam również (ogólnie) jednej wspólnej informacji o montażu na rozwiązanie, przy założeniu, że jedno rozwiązanie to pojedyncza linia produktów / produkt do wydania. Wspólny plik informacji o zespole zawiera również:

[assembly: AssemblyInformationalVersion("0.9.2.0")]

Który ustawi wartość „ProductVersion” wyświetlaną przez Eksploratora Windows.

Scott Dorman
źródło
8

Zadania społeczności MSBuild zawiera niestandardowe zadanie o nazwie AssemblyInfo, którego można użyć do wygenerowania pliku assemblyinfo.cs. Wymaga niewielkiej ręcznej edycji plików csproj, ale warto.

jlew
źródło
6

Moim zdaniem korzystanie z GlobalAssemblyInfo.cs jest bardziej kłopotliwe niż warte, ponieważ musisz zmodyfikować każdy plik projektu i pamiętać o modyfikacji każdego nowego projektu, podczas gdy domyślnie dostajesz AssemblyInfo.cs.

W przypadku zmian wartości globalnych (np. Firmy, produktu itp.) Zmiany są zwykle tak rzadkie i proste w zarządzaniu, że nie sądzę, aby kwestia DRY była brana pod uwagę. Po prostu uruchom następujący skrypt MSBuild (zależny od pakietu MSBuild Extension Pack ), jeśli chcesz ręcznie zmienić wartości we wszystkich projektach jako jednorazowe:

<?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
źródło
3

Aby udostępnić plik między wieloma projektami, możesz dodać istniejący plik jako łącze.

Aby to zrobić, dodaj istniejący plik i kliknij „Dodaj jako łącze” w selektorze plików. (źródło: free.fr )Dodaj jako łącze

Jeśli chodzi o to, co umieścić w udostępnionym pliku, sugerowałbym umieszczenie rzeczy, które byłyby udostępniane w zespołach. Rzeczy takie jak prawa autorskie, firma, być może wersja.

Cameron MacFarland
źródło
1

Używanie jednego pliku AseemblyInfo.cs dla wielu projektów nie jest zalecane. Plik AssemblyInfo zawiera informacje, które mogą być istotne tylko dla tego konkretnego zestawu. Dwie najbardziej oczywiste informacje to AssemblyTitlei AssemblyVersion.

Lepszym rozwiązaniem może być użycie targetspliku obsługiwanego przez MSBuild w celu „wstrzyknięcia” atrybutów zestawu do więcej niż jednego projektu.

SaguiItay
źródło
co jeśli masz ponad 20 projektów? Wymaga to ode mnie utrzymywania ponad 20 pozycji w mojej konfiguracji kompilacji, tylko do obsługi wersji. To wydaje się naprawdę kiepskie. A jeśli dodam 2 lub 3 nowe projekty? To z pewnością przerwie proces tworzenia… Jakieś pomysły, jak to rozwiązać?
D3vtr0n
@ D3vtr0n Myślę, że chodzi o to, aby dynamicznie generować odpowiedni zestaw, a nie utrzymywać indywidualnych konfiguracji dla każdego projektu. Myślę, że Zadania społeczności zajmują się tą sprawą.
Roman
1

Jedną z rzeczy, które uznałem za przydatne, jest generowanie elementów AssemblyVersion (itp.) Przez zastosowanie podstawiania tokenów w fazie wstępnej kompilacji.

Używam TortoiseSVN, i łatwo jest wykorzystać swoje SubWCRev.exewłączyć szablon AssemblyInfo.wcrevdo AssemblyInfo.cs. Odpowiednia linia w szablonie może wyglądać mniej więcej tak:

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

Trzeci element to numer rewizji. Czwartego elementu używam do sprawdzenia, czy nie zapomniałem zatwierdzić żadnych nowych lub zmienionych plików (czwarty element to 00, jeśli wszystko jest w porządku).

Nawiasem mówiąc, dodaj AssemblyInfo.wcrevdo kontroli wersji i zignoruj, AssemblyInfo.cs jeśli tego używasz.

John Denniston
źródło