Как выбрать разные app.config для нескольких конфигураций сборки - PullRequest
113 голосов
/ 10 ноября 2011

У меня есть проект типа 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, ...)?

Ответы [ 10 ]

150 голосов
/ 14 ноября 2011

Используйте плагин SlowCheetah .Дополнительные параметры и подробные сведения о том, как использовать SlowCheetah, продолжайте читать.

Как вы уже заметили, не существует стандартного и простого способа использования различных файлов конфигурации для Тип библиотеки (.dll) проект.Причина в том, что нынешнее мышление таково: «Вам не нужно»!Разработчики Framework считают, что вам нужна конфигурация для исполняемого файла: будь то консоль, рабочий стол, веб, мобильное приложение или что-то еще.Если вы начнете предоставлять конфигурацию для dll , у вас может получиться то, что я могу назвать config hell .Вы, возможно, больше не понимаете (легко), почему эта и эта переменные имеют такие странные значения, исходящие, казалось бы, из ниоткуда.

«Держись», - вы можете сказать, «но мне это нужно для моей интеграции / модульного тестирования,и это библиотека! "И это правда, и это то, что вы можете сделать (выберите только один, не смешивайте):

1.SlowCheetah - преобразует текущий файл конфигурации

. Вы можете установить SlowCheetah - плагин Visual Studio, который выполняет все низкоуровневые разбивки (или преобразования) XML.Кратко о том, как это работает:

  • Установите SlowCheetah и перезапустите Visual Studio (Visual Studio> Инструменты> Расширения и обновления ...> Онлайн> Галерея Visual Studio> поиск "Медленный гепард")
  • Определите свои конфигурации решения (по умолчанию Debug и Release ), вы можете добавить больше (щелкните правой кнопкой мыши по решению в Solution Explorer > Диспетчер конфигурации ... > Конфигурация активного решения > Новый ...
  • При необходимости добавьте файл конфигурации
  • Щелкните правой кнопкой мыши на файле конфигурации> Добавить преобразование
    • Это создаст файлы преобразования - один для вашей конфигурации
    • Файлы преобразования работают как инжекторы / мутаторы, они находят необходимый код XML висходный конфигурационный файл и вводить новые строки или изменять нужное значение, что бы вы ни сказали:

2. Скрипт с файлом .proj - копирование-переименование всего нового файла конфигурации

Первоначально взято from здесь .Это пользовательская задача MSBuild, которую вы можете встроить в файл Visual Studio .proj .Скопируйте и вставьте следующий код в файл проекта

<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\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>
22 голосов
/ 10 ноября 2011

Вы можете попробовать следующий подход:

  1. Щелкните правой кнопкой мыши проект в обозревателе решений и выберите Выгрузить проект .
  2. Проект будет выгружен. Снова щелкните правой кнопкой мыши по проекту и выберите Редактировать .csproj .
  3. Теперь вы можете редактировать файл проекта в Visual Studio.
  4. Найдите место в файле * .csproj, куда входит файл конфигурации вашего приложения. Это будет выглядеть так:
    <ItemGroup>
        <None Include="App.config"/>
    </ItemGroup>
  1. Заменить эти строки следующим:
    <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
        <None Include="App.Debug.config"/>
    </ItemGroup>

    <ItemGroup Condition=" '$(Configuration)' == 'Release' ">
        <None Include="App.Release.config"/>
    </ItemGroup>

Я не пробовал этот подход к app.config файлам, но он отлично работал с другими элементами проектов Visual Studio. Вы можете настроить процесс сборки практически любым способом. В любом случае, дайте мне знать результат.

12 голосов
/ 10 ноября 2011

Вы должны рассмотреть ConfigGen . Это было разработано для этой цели. Он создает файл конфигурации для каждого компьютера развертывания на основе файла шаблона и файла настроек. Я знаю, что это не отвечает конкретно на ваш вопрос, но вполне может ответить на вашу проблему.

Таким образом, вместо Отладки, Выпуска и т. Д. У вас могут быть Test, UAT, Production и т. Д. У вас также могут быть разные настройки для каждой машины разработчика, так что вы можете сгенерировать конфигурацию, специфичную для вашей машины разработчика, и изменить ее, не затрагивая никаких развертывание еще одного.

Примером использования может быть ...

<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).

10 голосов
/ 19 августа 2013

Используя тот же подход, что и Romeo, я адаптировал его к Visual Studio 2010:

 <None Condition=" '$(Configuration)' == 'Debug' " Include="appDebug\App.config" />

 <None Condition=" '$(Configuration)' == 'Release' " Include="appRelease\App.config" />

Здесь вам нужно хранить оба файла App.config в разных каталогах (appDebug и appRelease). Я проверил это, и он отлично работает!

3 голосов
/ 22 августа 2015

SlowCheetah и FastKoala из VisualStudio Gallery кажутся очень хорошими инструментами, которые помогают решить эту проблему.

Однако, если вы хотите избежать надстроек или использовать принципы, которые они более широко реализуют в вашей сборке / интеграцииПроцессы, затем добавление этого в ваши файлы 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 (или как вы ее называете), различные промежуточные файлы конфигурациидолжно иметь Действие сборки = Нет и Копировать в выходной каталог = Не копировать.

Это объединяет обе опции в один блок.Соответствующий выполняется в зависимости от условий.Задача 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>

3 голосов
/ 11 ноября 2011

Я использую XmlPreprocess tool для манипулирования файлами конфигурации.Он использует один файл отображения для нескольких сред (или нескольких целей сборки в вашем случае)Вы можете редактировать файл сопоставления в Excel.Это очень удобно.

1 голос
/ 02 августа 2018

Я слышал хорошие новости о Медленном Чите, но не смог заставить его работать. Я сделал следующее: добавил тег am к каждому для конкретной конфигурации.

Ex:

<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>
1 голос
/ 23 августа 2017

Я решил эту тему с помощью решения, которое нашел здесь: http://www.blackwasp.co.uk/SwitchConfig.aspx

Короче говоря, они говорят: "добавив событие после сборки. [...] Нам нужно добавить следующее:

if "Debug"=="$(ConfigurationName)" goto :nocopy
del "$(TargetPath).config"
copy "$(ProjectDir)\Release.config" "$(TargetPath).config"
:nocopy
1 голос
/ 10 февраля 2016

Посмотрите, может ли механизм преобразования XDT (web.config) помочь вам.В настоящее время он поддерживается только для веб-проектов, но технически ничто не мешает использовать его в других типах приложений.Существует множество руководств по использованию XDT при ручном редактировании файлов проекта, но я нашел плагин, который отлично работает: https://visualstudiogallery.msdn.microsoft.com/579d3a78-3bdd-497c-bc21-aa6e6abbc859

Плагин помогает только настроить конфигурацию, он не нужен для сборки ирешение может быть построено на других машинах или на сервере сборки без использования плагина или других инструментов.

0 голосов
/ 07 сентября 2014

После некоторых исследований по управлению конфигами для разработки, сборок и т. Д. Я решил свернуть свой собственный, я сделал его доступным для bitbucket по адресу: https://bitbucket.org/brightertools/contemplate/wiki/Home

Это несколько файлов конфигурации для нескольких сред, егоинструмент для замены базовой записи конфигурации, который будет работать с любым текстовым форматом файла.

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

...