Каковы лучшие практики использования атрибутов сборки?

163

У меня есть решение с несколькими проектами. Я пытаюсь оптимизировать файлы AssemblyInfo.cs, связав один информационный файл сборки для всего решения. Каковы лучшие практики для этого? Какие атрибуты должны быть в файле решения, а какие специфичны для проекта / сборки?


Изменить: Если вы заинтересованы, есть дополнительный вопрос Каковы различия между AssemblyVersion, AssemblyFileVersion и AssemblyInformationalVersion?

Якуб Штурц
источник

Ответы:

207

Мы используем глобальный файл с именем GlobalAssemblyInfo.cs и локальный файл с именем AssemblyInfo.cs. Глобальный файл содержит следующие атрибуты:

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

Локальный AssemblyInfo.cs содержит следующие атрибуты:

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

Вы можете добавить GlobalAssemblyInfo.cs, используя следующую процедуру:

  • Выберите Добавить / Существующий элемент ... в контекстном меню проекта
  • Выберите GlobalAssemblyInfo.cs
  • Разверните кнопку добавления, нажав на маленькую стрелку вниз справа
  • Выберите «Добавить как ссылку» в выпадающем списке кнопок
JRoppert
источник
Какова цель сохранения старого файла (файлов) AssemblyInfo.cs? Когда я автоматизирую свой штамп версии сборки в GlobalAssemblyInfo.cs, как это обновляет файл AssemblyInfo.cs, который есть в моем решении?
D3vtr0n
3
@Devtron Отдельные файлы AssemblyInfo должны предоставлять информацию, уникальную для сборки, в которой они находятся (например, заголовок, описание и культура, как в примере выше). Общие записи, такие как название продукта и информация о версии, должны быть удалены (и вызовут ошибку компилятора, если они будут дублированы). В идеале файлы AssemblyInfo не будут обновляться в процессе сборки.
Дэвид Кивини
1
AssemblyCultureAttributeЗаслуживает лучшего объяснения. Лучше всего, чтобы атрибут полностью отсутствовал (если это не спутниковая сборка). При использовании спутниковых сборок в больших масштабах может потребоваться три, а не два уровня информационных файлов сборок (глобальная сборка, основная сборка и вспомогательная сборка, в которой в этом случае указывается только культура).
Джирка Ханика
20

В моем случае мы создаем продукт, для которого у нас есть решение Visual Studio с различными компонентами в их собственных проектах. Общие атрибуты уходят. В решении имеется около 35 проектов и общая информация о сборке (CommonAssemblyInfo.cs), которая имеет следующие атрибуты:

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

Другие атрибуты, такие как AssemblyTitle, AssemblyVersion и т. Д., Мы предоставляем для каждой сборки. При сборке сборки оба AssemblyInfo.cs и CommonAssemblyInfo.cs встраиваются в каждую сборку. Это дает нам лучшее из обоих миров, где вы можете захотеть иметь общие атрибуты для всех проектов и конкретные значения для некоторых других.

Надеюсь, это поможет.

Кришна
источник
у вас есть 35+ записей в вашей конфигурации сборки, чтобы справиться с этим? Кажется довольно избыточным. Что, если вы добавите 2 или 3 новых проекта, это нарушит вашу сборку, пока вы не добавите их в задачу управления версиями?
D3vtr0n
1
@ D3vtr0n, зачем «конфигурации сборки» (что вы подразумеваете под этим) нужно так много записей? Я предполагаю, что этот файл включен в каждый .csproj через <Compile Include="$(MSBuildThisFileDirectory)..\Common\CommonAssemblyInfo.cs"/>директиву MSBuild, которая может даже находиться в общем Common.targetsфайле. Yay код повторного использования.
Бинки
15

Решение, представленное @JRoppert, почти такое же, как и у меня. Единственное отличие состоит в том, что я поместил следующие строки в локальный файл AssemblyInfo.cs, поскольку они могут различаться в зависимости от каждой сборки:

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

Я также (как правило) использую одну общую информацию о сборке для каждого решения, предполагая, что одно решение представляет собой одну линейку продуктов / выпускаемый продукт. Файл общей информации о сборке также имеет:

[assembly: AssemblyInformationalVersion("0.9.2.0")]

Который будет устанавливать значение «ProductVersion», отображаемое в проводнике Windows.

Скотт Дорман
источник
8

Задачи сообщества MSBuild содержат пользовательскую задачу AssemblyInfo, которую вы можете использовать для создания вашего assemblyinfo.cs. Это требует небольшого ручного редактирования ваших файлов csproj, но оно того стоит.

jlew
источник
6

По моему мнению, использование GlobalAssemblyInfo.cs - это больше проблем, чем оно того стоит, потому что вам нужно изменить каждый файл проекта и не забывать изменять каждый новый проект, тогда как вы получаете AssemblyInfo.cs по умолчанию.

Для изменений в глобальных ценностях (например, Компания, Продукт и т. Д.) Изменения, как правило, настолько редки и просты в управлении, что я не думаю, что DRY должно быть соображением. Просто запустите следующий скрипт MSBuild (зависит от пакета расширений MSBuild ), если вы хотите вручную изменить значения во всех проектах как разовые:

<?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>
Джек Уклея
источник
3

Чтобы поделиться файлом между несколькими проектами, вы можете добавить существующий файл в виде ссылки.

Для этого добавьте существующий файл и нажмите «Добавить как ссылку» в селекторе файлов. (источник: free.fr )Добавить как ссылку

Что касается того, что поместить в общий файл, я бы предложил поместить вещи, которые будут совместно использоваться в сборках. Такие вещи, как авторское право, компания, возможно, версия.

Кэмерон МакФарланд
источник
1

Использование одного файла AseemblyInfo.cs для нескольких проектов не рекомендуется. Файл AssemblyInfo содержит информацию, которая может иметь отношение только к этой конкретной сборке. Две наиболее очевидные части информации - это AssemblyTitleи AssemblyVersion.

Лучшим решением может быть использование targetsфайла, который обрабатывается MSBuild, чтобы «внедрить» атрибуты сборки в несколько проектов.

SaguiItay
источник
Что делать, если у вас более 20 проектов? Это требует от меня сохранения более 20 записей в конфигурации сборки, только для контроля версий. Это кажется действительно хромым. Что если я добавлю 2 или 3 новых проекта? Это определенно нарушит процесс сборки ... Есть идеи, как это решить?
D3vtr0n
@ D3vtr0n Я думаю, что идея состоит в том, чтобы динамически генерировать отдельную сборку, а не поддерживать отдельные конфигурации для каждого проекта. Задачи сообщества, я думаю, решают эту проблему.
Роман
1

Одна вещь, которую я нашел полезной, - это генерирование элементов AssemblyVersion (и т. Д.) Путем применения замены токенов на этапе предварительной сборки.

Я использую TortoiseSVN, и легко использовать его , SubWCRev.exeчтобы включить шаблон AssemblyInfo.wcrevв AssemblyInfo.cs. Соответствующая строка в шаблоне может выглядеть примерно так:

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

Третий элемент - это номер редакции. Я использую четвертый элемент, чтобы проверить, что я не забыл зафиксировать какие-либо новые или измененные файлы (четвертый элемент - 00, если все в порядке).

Кстати, добавьте AssemblyInfo.wcrevв свой контроль версий и игнорируйте, AssemblyInfo.cs если вы используете это.

Джон Деннистон
источник