Comments 11
А можно просто создать по конфигурации на бранч и включить трансформацию конфигов при каждой сборке проекта (не путать с трансформацией при деплое). Например, так:
Web.Base.Config + Web.$(Configuration).config = Web.Config
То, что собранный Web.Config
будет попадать в pending changes — не имеет никакого значения, поскольку он все равно перезапишется при следующем билде соответственно выбранной конфигурации. Оригинал хранится в Web.Base.Config
и правится редко. На билд-сервере трансформация тоже будет работать.
Будут. Но на практике, основной проблемой, с которой мы сталкивались, оказалось — приучить коллег проверять, у каждого ли проекта в солюшене выставлена правильная конфигурация в Configuration Manager. И не забывать добавлять наши кастомные конфигурации для новых проектов, что, впрочем, легко диагностировалось по падению сборки на билд-сервере.
Наоборот удобно — в web.config не попадает всякий мусор. А нужные вещи можно и перенести вручную...
Чтобы собранный web.config не попадал в pending changes — его надо добавлять в .gitignore (или анологичный список файлов для других VCS)!
Я решал эту задачу используя штатный Web.config Transformation:
1) Добавляем /Web.config в .gitignore
2) Создаем конфигурации для требуемых вариантов сборки:
- /App_Config/Web.config
- /App_Config/Web.Release.config
- /App_Config/Web.Stage.config
3) Добавляем небольшой код в файл проекта:
<PropertyGroup>
<SiteConfigDir>$(MSBuildProjectDirectory)\App_Config</SiteConfigDir>
<SiteRootDir>$(MSBuildProjectDirectory)</SiteRootDir>
</PropertyGroup>
<Target Name="ProcessConfigFiles">
<TransformXml Condition="Exists('$(SiteConfigDir)\Web.$(Configuration).config')" Source="$(SiteConfigDir)\Web.config" Transform="$(SiteConfigDir)\Web.$(Configuration).config" Destination="$(SiteRootDir)\Web.config" StackTrace="true" />
<Copy Condition="!Exists('$(SiteConfigDir)\Web.$(Configuration).config')" SourceFiles="$(SiteConfigDir)\Web.config" DestinationFolder="$(SiteRootDir)" OverwriteReadOnlyFiles="true" />
</Target>
<Target Name="AfterBuild">
<CallTarget Targets="ProcessConfigFiles" />
</Target>
Pros:
- \Web.config не попадает в pending changes
- все варианты настроек хранятся в git.
Cons:
- нужно не забывать, что правки требуется вносить в /App_Config/Web.config, а не в /Web.config.
- после изменения конфигурации нужно пересобрать проект
Ну, в общем случае настройка окружения не ограничивается только appSettings. Как минимум, еще будет system.net\mailSettings, connectionStrings, system.web\customErrors, содержимое system.serviceModel, настройки логов (nlog и/или system.diagnostic). Так что держать все это в одном файле, как мне кажется, проще.
Если честно, то приведенный выше пример я давно не использую. Сейчас предпочитаю хранить в appSettings один параметр DeployMode, на основе которого производится конфигурация IoC-контейнера. Получается более гибко, плюс строгая типизация не даст что-нибудь забыть.
Изменение содержимого Web.config в runtime при отладке в Visual Studio и IISExpress