Как условно развернуть app.config на основе конфигурации сборки?

У меня есть три пользовательских конфигурации сборки {Dev, Qs, Prd}. Итак, у меня есть три конфигурации приложений: {Dev.config, Qs.config, Prd.config}. Я знаю, как отредактировать файл .csproj для вывода правильного файла на основе текущей конфигурации сборки.

<Target Name="AfterBuild">
   <Delete Files="$(TargetDir)$(TargetFileName).config" />
   <Copy SourceFiles="$(ProjectDir)$(Configuration).config" DestinationFiles="$(TargetDir)$(TargetFileName).config" />
</Target>

Моя проблема в том, что мне нужно иметь шесть конфигураций сборки {Dev, Qs, Prd} x {Debug, Release}. Мне нужно поддерживать настройки отладки и выпуска (оптимизации, pdb и т. Д.) Для каждой среды. Однако значения конфигурации приложения не меняются между отладкой / выпуском.

Как сделать сценарий сборки максимально универсальным и использовать только три конфигурации приложения? Я не хочу жестко кодировать слишком много условных строк.


person Anthony Mastrean    schedule 08.12.2008    source источник
comment
Тег ‹Target /› поддерживает атрибут Condition. Могу ли я проверить, соответствует ли условие Dev_ * (как в Dev_Debug или Dev_Release), чтобы использовать файл Dev.config?   -  person Anthony Mastrean    schedule 08.12.2008
comment
Вот хорошее ‹a href=hanselman.com/blog/ на scott Hanselmans ‹/a› об автоматизации множественной конфигурации. В разделе комментариев есть несколько альтернативных решений. Кое-что интересное вроде работы с дельтой конфигурационных файлов. Некоторые другие похожи на разные файлы конфигурации для разной среды.   -  person Biswanath    schedule 09.12.2008
comment
Просто для справки для будущих читателей: я попробовал приведенный выше код, и он сработал, но НЕ для развертывания с помощью ClickOnce. Его просто не было в комплекте. Таким образом, я выбрал решение от blogs.msdn.com/b/vsto/archive/2010/03/09/, что похоже на ответ Стива.   -  person chiccodoro    schedule 25.08.2010


Ответы (5)


Что-то вроде

<PropertyGroup Condition="'$(Configuration)'=='Dev_Debug' OR '$(Configuration)'=='Dev_Release'" >
    <CfgFileName>Dev</CfgFileName>
</PropertyGroup>
<!-- similar for Qs & Prd -->
<Target ...>...$(CfgFileName).config...
person Brian    schedule 08.12.2008
comment
Это работает, пока я не добавлю третью настраиваемую конфигурацию сборки. Я получаю сообщение об ошибке: не могу найти ‹blah› \ .config. Я думаю, это может быть проблема с моим окружением. Я сомневаюсь, хочу ли я поддерживать такую ​​большую конфигурацию .csproj. - person Anthony Mastrean; 08.12.2008

Мы исправили это с помощью элемента Выбрать в файле csproj. У нас настроено несколько различных конфигураций, поэтому все, что мы делаем, это помещаем этот блок в ваш proj-файл, и вы можете использовать конфигурацию VS, чтобы помочь вам. Я хочу повторить совет Роба по перемещению переданного app.config. Некоторое время я двигался в этом направлении.

  <Choose>
<When Condition=" '$(Configuration)' == 'Debug' ">
  <ItemGroup>
    <None Include="App.config" />
    <None Include="Release\App.config" />
  </ItemGroup>
</When>
<Otherwise>
  <ItemGroup>
    <None Include="Release\App.config">
      <Link>App.config</Link>
    </None>
  </ItemGroup>
</Otherwise>

person Steve Severance    schedule 08.12.2008

Я предлагаю, чтобы ваш вопрос показал, что вы переросли _1 _ - пора перейти к лучшему решению и начать решать некоторые связанные с этим проблемы.

Во-первых, вам НИКОГДА не следует автоматически развертывать файл конфигурации в производственной среде, и вы должны ожидать, что персонал технической поддержки категорически отвергнет любую попытку сделать это. Конечно, если вы обслуживаете персонал, то вам следует отказаться от него самостоятельно. Вместо этого ваш выпуск должен включать некоторые инструкции по обновлению файла конфигурации вручную с примером для иллюстрации. Конфигурация производства слишком важна для меньших мер, если вы просто не очень цените свою производственную систему.

То же самое для тестовой и других сред, но в меньшей степени, поэтому вам действительно нужно заполнить app.config только для вашей собственной разработки.

Можно встроить несколько конфигураций в одну app.config, что разумно для небольших, относительно неважных приложений или на ранних стадиях разработки / выпуска. Например, создайте параметр конфигурации, называемый чем-то вроде target-env, который содержит значение, которое вы используете в своем коде для выбора других параметров конфигурации, например, добавляя значение к ключам других параметров конфигурации.

Я предпочитаю полностью отказаться от app.config или использовать его минимально. В этом случае я предпочитаю помещать в файл столько данных конфигурации, чтобы позволить моему приложению / системе подключаться к своей базе данных, а затем я помещаю оставшиеся детали конфигурации в специальную таблицу базы данных для этой цели. Это имеет множество преимуществ, таких как «осведомленность» базы данных о том, какую среду она представляет (для разработки, тестирования, производства и т. Д.), И сохранение конфигурации и других данных вместе. В этом случае пакет развертывания можно правильно не показывать в отношении конфигураций и различий в средах - код просто получает доступ к своим данным конфигурации и действует соответствующим образом, поэтому один и тот же пакет развертывания подходит для любой среды.

Однако ключевым фактором успеха этого подхода является то, что код вашего приложения должен «знать», что он ожидает от конфигурации, и он должен «знать», чтобы отклонить неправильную / неполную конфигурацию. Здесь вам следует проводить время, а не пытаться обойти ограничения app.config.

Обычно это означает создание собственного класса для доступа к данным конфигурации, а затем использование этого класса во всем приложении. Это также приводит ко многим другим преимуществам, таким как строго типизированные данные конфигурации: вместо String возвращайте DateTime, или Url, или Integer, или Currency, или то, что лучше всего подходит для данных конфигурации и приложения.

person Rob Williams    schedule 08.12.2008
comment
В конфиге 10-15 пунктов: URL, список удаленных объектов, список файлов. Я отделяю источник конфигурации от формата по интерфейсу. Конфигурация приложения - вероятный и ожидаемый источник. Я предпочитаю ручное обновление как часть процесса сборки, но я должен исследовать этот путь для моего босса. - person Anthony Mastrean; 08.12.2008
comment
Во-первых, вам НИКОГДА не следует автоматически развертывать файл конфигурации в производственной среде. Попробуйте сообщить об этом Microsoft! Кое-что из того, что они сегодня вставляют в файл app / web.config, действительно должно быть скомпилировано в exe-файл. - person Martin Brown; 09.12.2008
comment
Да, что ж, я счел бесполезным пытаться что-либо сообщить Microsoft - я просто пытаюсь защитить себя и своего клиента от воздействия. Это прекрасная иллюстрация необходимых изменений при переходе к развертыванию корпоративного класса. - person Rob Williams; 09.12.2008
comment
Я согласен с большей частью вышеперечисленного, за исключением того, что это означает, что app.config подходит только для самых простых конфигураций. Вы предлагаете реализовать индивидуальное конфигурационное решение? Как быть в этом случае с технологиями профессионального уровня, которые полагаются на управление конфигурацией, такими как WCF, веб-приложения и т. Д.? Потребность определенно существует. Что касается поддержки операций, запрещающих автоматически развертываемые файлы конфигурации - ясно сказано, что вам не следует развертывать что-то, что может быть изменено в процессе работы, однако многие разработчики устанавливают свои собственные политики в этом отношении. - person Sprague; 16.02.2011
comment
@RobWilliams Не могли бы вы объяснить, почему так плохо развертывать файл app.config автоматически? - person Rustam Miftakhutdinov; 16.04.2014
comment
Во-первых, вы НИКОГДА не должны автоматически развертывать файл конфигурации в производственной среде, по вашему мнению, точка. Тонны людей используют CI для развертывания изменений в производственной среде несколько раз в день (например, этот веб-сайт). - person Wjdavis5; 05.05.2016

Как насчет использования сервера сборки?
Прошло много времени с тех пор, как я работал в .NET, но разве вы не можете использовать Hudson (-подобный) сервер для управления конфигурациями сборки? Не проще ли?
А как насчет NAnt? Разве это не соответствует вашим потребностям?

person Nimrod Shory    schedule 03.12.2009
comment
Джеймс, ты прав. На данный момент мы переросли возможности (и чувствительность) использования файла csproj. - person Anthony Mastrean; 03.12.2009

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

{ Dev_Debug.config, Dev_Release.config, Qs_Debug.config, ... , Prd_Release.config }.

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

person Anthony Mastrean    schedule 08.12.2008