Скачать исходный код |
Начнем рассмотрение работы с config-файлами с самой простой темы. Создадим приложение ASP.NET MVC 4. По-умолчанию в созданном проекте уже есть 2 конфигурации (Debug, Release) и 3 config-файла (Web.config, Web.Debug.config, Web.Release.config):
Сгенерированные файлы Web.Debug.config и Web.Release.config содержат немного полезного кода. Для демонстрации их возможностей добавим замену строки подключения к БД в разных конфигурациях сборки. Получим следующие файлы:
Web.config
... <connectionStrings> <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-MvcApplication-20130502094058;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-MvcApplication-20130502094058.mdf" providerName="System.Data.SqlClient" /> </connectionStrings> ...
Web.Debug.config
<?xml version="1.0"?> <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <connectionStrings> <add xdt:Transform="Replace" xdt:Locator="Match(name)" name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-MvcApplication-20130502094058;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-MvcApplication-20130502094058.mdf" providerName="System.Data.SqlClient" /> </connectionStrings> </configuration>
Web.Release.config
<?xml version="1.0"?> <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> <connectionStrings> <add xdt:Transform="Replace" xdt:Locator="Match(name)" name="DefaultConnection" connectionString="Data Source=10.10.0.1;Initial Catalog=ProductionDB;User Id=username; Password=password;" providerName="System.Data.SqlClient" /> </connectionStrings> </configuration>
Файлы конфигураций Web.Debug.config и Web.Release.config содержат схемы трансформации. В нашем случае мы будем трансформировать файл Web.config. С помощью xdt:Transform="Replace" поменяем значение атрибута connectionString.
Из примера видно, что для конфигурации Debug будет использоваться локальная БД. Конфигурация Release пойдет на боевой сервер, поэтому в строке подключения мы указали путь до БД MSSQL, с которой работают конечные пользователи.
Более подробно о синтаксисе трансформации можно прочитать на MSDN.
Target AfterBuild
Теперь сделаем автоматическую трансформацию Web.config во время сборки проекта. Для этого добавим вызов TransformXml в target AfterBuild нашего проекта:
MvcApplication.csproj:
... <Target Name="AfterBuild"> <TransformXml Source="Web.config" Transform="Web.$(Configuration).config" Destination="Web.config" StackTrace="true" /> </Target> ...
Если мы поменяем конфигурацию сборки на Release и сделаем Build проекта, то в файле Web.config получим следующее:
Как мы видим, наш файл Web.config был изменен. В строку подключения подставились данные из Web.Release.config. Если выставить конфигурацию Debug и сделать Build, то в строку подключения подставится значение из Web.Debug.config.
Использование трансформации при Deploy
При сборке проекта можно посмотреть Output:
... 1> Configuration=Release ... Target "AfterBuild" in project "..\MvcApplication\MvcApplication\MvcApplication.csproj" (target "Build" depends on it): 1>Using "TransformXml" task from assembly "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web\Microsoft.Web.Publishing.Tasks.dll". 1>Task "TransformXml" 1> Transforming Source File: Web.config 1> Applying Transform File: Web.Release.config 1> Executing Replace (transform line 4, 10) 1> on /configuration/connectionStrings/add[@name='DefaultConnection'] 1> Applying to 'add' element (source line 7, 6) 1> Replaced 'add' element 1> Done executing Replace 1> Output File: Web.config 1> Transformation succeeded 1>Done executing task "TransformXml". 1>Done building target "AfterBuild" in project "MvcApplication.csproj". ...
Получается, что для создания релиза, нам достаточно во время сборки проекта указать конфигурацию Release и к Web.config будет применена соответствующая трансформация.
При таком подходе нам уже не надо помнить про изменение строки подключения к БД, изменение произойдет автоматически. Это исключит ручную работу с файлами конфигурации, что снизит количество ошибок при заливках.
Обратите внимание, что схему трансформации можно применять к любой секции config-файлов. Это могут быть appSettings, customErrors и другие. Замена строки подключения приведена, как самый наглядный и популярный пример.
Статья из серии Continuous Integration: Работа с Config-файлами:
Отлично! Задумался об использовании.
ОтветитьУдалитьАлександр,
ОтветитьУдалитьЧто Вы делаете когда в release трансформации находятся production пароли которые не хотелось бы хранить вместе с исходным кодом?
В любом случае их где-то надо хранить. Вы их в отдельном репозитории держите?
ОтветитьУдалитьДа, мы в отдельном.
ОтветитьУдалитьПроцедура релиза состоит из 2-х шагов: build и deploy. На шаге deploy и накладываем трансформацию которая храниться в секретном репозитории
Это интересно. Получается у вас не все имеют доступ к Deploy?
ОтветитьУдалитьВы где-то описывали ваш процесс выпуска релиза? Я бы почитал :)
У нас есть dev, stage, prod развертывания. Причем prod развертываний может быть несколько (грубо говоря под каждого клиента свое развертывание). Доступ открыт ко всем, кроме prod.
ОтветитьУдалитьПроцедура выпуска нигде не описана, как будет время напишу и поделюсь ссылкой
Добрый день!
ОтветитьУдалитьАлександр,
А что делать если у меня не вебконфиг а апп конфиг и виндовое приложение ? такой возможности там нет , как поступать в таком случае?
Я как раз к следующей неделе пишу в цикл очередную статью Continuous Integration: Трансформация App.config
ОтветитьУдалитьВы можете сейчас конкретные вопросы задать, чтобы я их сразу осветил.
Активно использую web.config transformation, однако тут есть один большой минус - трансформация возможна только при сборке приложения, а не при развёртывании. Таким образом невозможно использовать подход к деплою приложения на основе артифактов - уже собранных приложений. Почти все билд серверы (за исключением TFS) имеют возможность публиковать результаты сборки. На мой взгляд более верным является способ делать publish уже собранных сборок и уже потом делать трансформацию. В противном случае необходимо под каждое окружение делать отдельную сборку - qa, stage, live.
ОтветитьУдалить