Как выбрать другой app.config для нескольких конфигураций сборки
У меня есть проект dll-типа, который содержит тесты интеграции MSTest. На моей машине тесты проходят, и я хочу, чтобы то же самое происходило на сервере CI (я использую TeamCity). Но тесты терпят неудачу, потому что мне нужно настроить некоторые параметры в app.config. Вот почему я думал иметь отдельный второй файл app.config, который будет содержать настройки для сервера CI.
Итак, я хотел бы иметь
/Sln
/Proj
app.config (I think this is required by VS)
app.Release.config (This is a standalone independent config file)
Таким образом, если я выберу конфигурацию Release в конфигурации сборки в CI, я бы хотел использовать файл app.Release.config вместо app.config
Проблема
Это не похоже на простые проекты типа .dll. Для веб-проектов я могу делать преобразования веб-конфигурации. Я нашел хак, как сделать эти преобразования для проекта типа dll, но я не большой поклонник хаков.
Вопрос
Что такое стандартный подход к настройке файлов app.config в зависимости от конфигурации сборки для проектов .NET(таких как Debug, Release,...)?
Ответы
Ответ 1
Используйте плагин SlowCheetah. Для получения дополнительных опций и подробностей о том, как использовать SlowCheetah, продолжайте читать.
Как вы уже заметили, нет никакого стандартного и простого способа использования разных конфигурационных файлов для проекта типа библиотеки (DLL). Причина в том, что нынешнее мышление: "Вам не нужно"! Разработчики рамок считают, что вам нужна конфигурация для исполняемого файла: будь то консоль, рабочий стол, веб-приложение, мобильное приложение или что-то еще. Если вы начнете предоставлять конфигурацию для dll, вы можете получить что-то, что я могу назвать конфигурационным адом. Вы можете больше не понимать (легко), почему эта и эти переменные имеют такие странные ценности, которые кажутся из ниоткуда.
"Держись", - можешь сказать, - но мне это нужно для интеграции/модульного тестирования, и это библиотека! ". И это правда, и это то, что вы можете сделать (выберите только один, не смешивайте):
1. SlowCheetah - преобразует текущий файл конфигурации
Вы можете установить SlowCheetah - подключаемый модуль Visual Studio, который выполняет все ваши низкоуровневые XML-трюки (или преобразования). Как это работает, кратко:
- Установите SlowCheetah и перезапустите Visual Studio (Visual Studio > Инструменты > Расширения и обновления... > Интернет > Галерея Visual Studio > найдите "Медленный гепард" )
- Определите свои конфигурации решений (по умолчанию есть Debug и Release), вы можете добавить больше (щелкните правой кнопкой мыши по решению в обозревателе решений > Configuration Manager... > Конфигурация Active Solution > Создать...
- При необходимости добавьте файл конфигурации
- Щелкните правой кнопкой мыши файл конфигурации > Добавить преобразование
- Это создаст файлы Transformation - по одному для вашей конфигурации
- Преобразование файлов работает как инжекторы/мутаторы, они находят необходимый XML-код в исходном файле конфигурации и вводят новые строки или изменяют необходимое значение, что бы вы ни говорили вам сделать
2. Скрипт с .proj файлом - копирует-переименовывает весь новый файл конфигурации
Первоначально взято из здесь. Это настраиваемая задача MSBuild, которую вы можете встроить в файл .proj Visual Studio. Скопируйте и вставьте следующий код в файл проекта
<Target Name="AfterBuild">
<Delete Files="$(TargetDir)$(TargetFileName).config" />
<Copy SourceFiles="$(ProjectDir)\Config\App.$(Configuration).config"
DestinationFiles="$(TargetDir)$(TargetFileName).config" />
</Target>
Теперь создайте папку в проекте под названием Config
и добавьте туда новые файлы: App.Debug.config, App.Release.config и т.д. Теперь, в зависимости от вашей конфигурации, Visual Studio выберет конфигурационный файл из папки Config
и скопирует его в каталог вывода. Поэтому, если у вас есть проект PatternPA.Test.Integration и выбранная конфигурация Debug, в выходной папке после сборки вы найдете файл PatternPA.Test.Integration.dll.config, который был скопирован из Config\App.Debug.config
и впоследствии переименован.
Вот некоторые заметки, которые вы можете оставить в конфигурационных файлах
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- This file is copied and renamed by the 'AfterBuild' MSBuild task -->
<!-- Depending on the configuration the content of projectName.dll.config
is fully substituted by the correspondent to build configuration file
from the 'Config' directory. -->
</configuration>
В Visual Studio вы можете иметь что-то вроде этого
![Project structure]()
3. Использовать скриптовые файлы вне Visual Studio
Каждый инструмент построения (например NAnt, MSBuild) предоставит возможности для преобразования конфигурационного файла в зависимости от конфигурации. Это полезно, если вы строите свое решение на машине сборки, где вам нужно больше контролировать, что и как подготовить продукт к выпуску.
Например, вы можете использовать задачу веб-публикации dll для преобразования любого файла конфигурации
<UsingTask AssemblyFile="..\tools\build\Microsoft.Web.Publishing.Tasks.dll"
TaskName="TransformXml"/>
<PropertyGroup>
<!-- Path to input config file -->
<TransformInputFile>path to app.config</TransformInputFile>
<!-- Path to the transformation file -->
<TransformFile>path to app.$(Configuration).config</TransformFile>
<!-- Path to outptu web config file -->
<TransformOutputFile>path to output project.dll.config</TransformOutputFile>
</PropertyGroup>
<Target Name="transform">
<TransformXml Source="$(TransformInputFile)"
Transform="$(TransformFile)"
Destination="$(TransformOutputFile)" />
</Target>
Ответ 2
Вы можете попробовать следующий подход:
- Щелкните правой кнопкой мыши проект в обозревателе решений и выберите Выгрузить проект.
- Проект будет выгружен. Щелкните правой кнопкой мыши проект еще раз и выберите Изменить <YourProjectName> .cproj.
- Теперь вы можете редактировать файл проекта внутри Visual Studio.
- Найдите место в файле *.csproj, в который включен ваш файл конфигурации приложения. Он будет выглядеть следующим образом:
<ItemGroup>
<None Include="App.config"/>
</ItemGroup>
- Замените следующие строки:
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<None Include="App.Debug.config"/>
</ItemGroup>
<ItemGroup Condition=" '$(Configuration)' == 'Release' ">
<None Include="App.Release.config"/>
</ItemGroup>
Я не пробовал этот подход к файлам app.config
, но он отлично работал с другими элементами проектов Visual Studio. Вы можете настроить процесс сборки практически любым способом. В любом случае, дайте мне знать результат.
Ответ 3
Вы должны рассмотреть ConfigGen. Он был разработан для этой цели. Он создает файл конфигурации для каждой машины развертывания на основе файла шаблона и файла настроек. Я знаю, что это не отвечает на ваш вопрос конкретно, но это может хорошо ответить на вашу проблему.
Чтобы вместо Debug, Release и т.д. у вас могли быть Test, UAT, Production и т.д. У вас также могут быть разные настройки для каждой машины для разработчиков, так что вы можете создать конфигурацию, специфичную для вашей машины dev, и изменить ее, не затрагивая никаких еще одно развертывание.
Пример использования может быть...
<Target Name="BeforeBuild">
<Exec Command="C:\Tools\cfg -s $(ProjectDir)App.Config.Settings.xls -t
$(ProjectDir)App.config.template.xml -o $(SolutionDir)ConfigGen" />
<Exec Command="C:\Tools\cfg -s $(ProjectDir)App.Config.Settings.xls -t
$(ProjectDir)App.config.template.xml -l -n $(ProjectDir)App.config" />
</Target>
Если вы поместите это в свой файл .csproj, и у вас есть следующие файлы...
$(ProjectDir)App.Config.Settings.xls
MachineName ConfigFilePath SQLServer
default App.config DEVSQL005
Test App.config TESTSQL005
UAT App.config UATSQL005
Production App.config PRODSQL005
YourLocalMachine App.config ./SQLEXPRESS
$(ProjectDir)App.config.template.xml
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<configuration>
<appSettings>
<add key="ConnectionString" value="Data Source=[%SQLServer%];
Database=DatabaseName; Trusted_Connection=True"/>
</appSettings>
</configuration>
... тогда это будет результат...
Из первой команды создается файл конфигурации, созданный для каждой среды, указанной в файле xls, помещенный в выходной каталог $(SolutionDir) ConfigGen
.../solutiondir/ConfigGen/Production/App.config
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<configuration>
<appSettings>
<add key="ConnectionString" value="Data Source=PRODSQL005;
Database=DatabaseName; Trusted_Connection=True"/>
</appSettings>
</configuration>
Из второй команды локальный файл App.config, используемый на вашем компьютере-разработчике, будет заменен на сгенерированную конфигурацию, указанную локальным (-l) коммутатором и именем файла (-n).
Ответ 4
Используя тот же подход, что и Romeo, я адаптировал его к Visual Studio 2010:
<None Condition=" '$(Configuration)' == 'Debug' " Include="appDebug\App.config" />
<None Condition=" '$(Configuration)' == 'Release' " Include="appRelease\App.config" />
Здесь вам нужно хранить файлы App.config в разных каталогах (appDebug и appRelease). Я тестировал его, и он отлично работает!
Ответ 5
Я использую инструмент XmlPreprocess для манипулирования конфигурационными файлами. Он использует один файл сопоставления для нескольких сред (или нескольких целей сборки в вашем случае). Вы можете редактировать файл сопоставления Excel. Он очень прост в использовании.
Ответ 6
SlowCheetah и FastKoala из галереи VisualStudio - это очень хорошие инструменты, которые помогают справиться с этой проблемой.
Однако, если вы хотите избежать добавления или использовать принципы, которые они реализуют более широко во всех ваших процессах сборки/интеграции, добавление этого в ваши файлы msbuild * proj является сокращенным исправлением.
Примечание: это более или менее передел № 2 ответа @oleksii.
Это работает для проектов.exe и.dll:
<Target Name="TransformOnBuild" BeforeTargets="PrepareForBuild">
<TransformXml Source="App_Config\app.Base.config" Transform="App_Config\app.$(Configuration).config" Destination="app.config" />
</Target>
Это работает для веб-проектов:
<Target Name="TransformOnBuild" BeforeTargets="PrepareForBuild">
<TransformXml Source="App_Config\Web.Base.config" Transform="App_Config\Web.$(Configuration).config" Destination="Web.config" />
</Target>
Обратите внимание, что этот шаг происходит еще до начала сборки. Преобразование конфигурационного файла происходит в папке проекта. Так что преобразованный web.config доступен, когда вы отлаживаете (недостаток SlowCheetah).
Помните, что если вы создаете папку App_Config (или что бы вы ни выбрали для ее вызова), различные промежуточные файлы конфигурации должны иметь Build Action = None и Copy to Output Directory = Не копировать.
Это объединяет оба варианта в один блок. Соответствующий выполняется на основе условий. Задача TransformXml определяется сначала:
<Project>
<UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\Web\Microsoft.Web.Publishing.Tasks.dll" />
<Target Name="TransformOnBuild" BeforeTargets="PrepareForBuild">
<TransformXml Condition="Exists('App_Config\app.Base.config')" Source="App_Config\app.Base.config" Transform="App_Config\app.$(Configuration).config" Destination="app.config" />
<TransformXml Condition="Exists('App_Config\Web.Base.config')" Source="App_Config\Web.Base.config" Transform="App_Config\Web.$(Configuration).config" Destination="Web.config" />
</Target>
Ответ 7
Посмотрите, поможет ли вам механизм преобразования XDT (web.config). В настоящее время он поддерживается только для веб-проектов, но технически нет ничего, что помешало бы вам использовать его в других типах приложений. Есть много руководств о том, как использовать XDT, вручную редактируя файлы проекта, но я нашел плагин, который отлично работает: https://visualstudiogallery.msdn.microsoft.com/579d3a78-3bdd-497c-bc21-aa6e6abbc859
Плагин только помогает настроить конфигурацию, ее не нужно строить, и решение может быть создано на других машинах или на сервере сборки без плагина или любых других необходимых инструментов.
Ответ 8
После некоторых исследований по управлению конфигурациями для разработки и сборки и т.д., я решил опрокинуть свой собственный, я сделал его доступным на битбакете по адресу: https://bitbucket.org/brightertools/contemplate/wiki/Home
Это несколько файлов конфигурации для нескольких сред, это базовый инструмент замены записи конфигурации, который будет работать с любым текстовым файлом.
Надеюсь, что это поможет.
Ответ 9
Я решил эту тему с решением, которое я нашел здесь:
http://www.blackwasp.co.uk/SwitchConfig.aspx
Короче говоря, они заявляют:
"добавив событие post-build. [...] Нам нужно добавить следующее:
if "Debug"=="$(ConfigurationName)" goto :nocopy
del "$(TargetPath).config"
copy "$(ProjectDir)\Release.config" "$(TargetPath).config"
:nocopy
Ответ 10
Я слышал хорошие вещи о SlowCheetah, но не смог заставить его работать. Я сделал следующее: добавьте тег am к каждому для определенной конфигурации.
Пример:
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'UAT|AnyCPU'">
<OutputPath>bin\UAT\</OutputPath>
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AppConfig>App.UAT.config</AppConfig>
</PropertyGroup>