MSBuild Contrib XMLMassUpdate и конфигурация NHibernate
Я пытаюсь создать файл MSBuild для развертывания набора из нескольких веб-сайтов в нескольких средах. На данный момент я создал проект и поместил его в каталог.
Я использую переменную $(AdminConsoleConfigFilePath), чтобы указать путь к файлу web.config в этом каталоге. Мой файл подстановок обозначается переменной $(AdminConsoleConfigReplacementFile). Я поставил следующую задачу в моем файле msbuild для проекта:
<Target Name="AdminConsoleConfig" DependsOnTargets="BuildAdminConsole">
<Message Text="Beginning configuration for AdminConsole at $(AdminConsoleConfigFilePath) using $(AdminConsoleConfigReplacementFile)" Importance="high"/>
<XmlMassUpdate ContentFile="$(AdminConsoleConfigFilePath)" SubstitutionsFile="$(AdminConsoleConfigurationReplacementPath)"
ContentRoot="$(ConfigurationContentReplacementXPathRoot)" SubstitutionsRoot="$(SubstitutionsXPathRoot)"/>
<Message Text="Finished configuration for AdminConsole using $(AdminConsoleConfigReplacementFile)" Importance="high"/>
`
Значения других переменных здесь объявлены следующим образом:
<ConfigurationContentReplacementXPathRoot>/configuration</ConfigurationContentReplacementXPathRoot>
<SubstitutionsXPathRoot>/configuration/substitutions/$(Environment)</SubstitutionsXPathRoot>
Окружение - это имя, на которое ориентирована сборка. В данном случае это "ка".
Мой web.config имеет типичный раздел hibernate-config следующим образом:
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="connection.isolation">ReadCommitted</property>
<property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string">[redacted]</property>
<property name="show_sql">false</property>
<property name="generate_statistics">true</property>
<property name="current_session_context_class">web</property>
<property name="adonet.batch_size">250</property>
<property name="proxyfactory.factory_class">NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle</property>
<mapping assembly="[redacted]"/>
</session-factory>
</hibernate-configuration>
Мой файл замен выглядит следующим образом:
<configuration xmlns:xmu="urn:msbuildcommunitytasks-xmlmassupdate">
<substitutions>
<dev></dev>
<qa>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property xmu:key="name" xmu:Transform="Replace" xmu:Locator="Match(name)" name="connection.connection_string">[redacted-qa]</property>
</session-factory>
</hibernate-configuration>
</qa>
Теперь свойство connection.connection_string не заменяется (в приведенном выше коде я также никогда не смог получить закрывающие теги для конфигурации и подстановки для отображения в редакторе на этом сайте - это может быть проблемой Firefox). Есть идеи? Я пробовал следующее:
- удаление объявления пространства имен для nhibernate-configuration из рассматриваемого web.config и файла замены (как вместе, так и по отдельности).
- Добавление префикса пространства имен к объявлению nhibernate и добавление к нему префиксов соответствующих узлов и атрибутов. Опять же, попробовал как на web.config, так и на файле замены, как по отдельности, так и в комбинации.
- Попытка использовать последнюю ночную сборку из проекта MSBuild contrib. Это не только не сработало, но и сломало другие вещи.
- Пробовал использовать xmu:Locator на основе XPath. Также пробовал как с, так и без значения xmu:key (и даже пытался заменить его на xmu:Key).
Я абсолютно в тупик. Работает ли XMLMassUpdate вообще? Мы бы хотели, чтобы qa и производственные версии web.config (или, по крайней мере, различные чувствительные биты) не попадали в основную часть кода на случай, если мы примем младшего разработчика или подрядчика, поэтому текущий метод На данный момент web.qa.config и web.prod.config не являются жизнеспособными. Есть какие-нибудь мысли о том, как это реализовать (кроме очевидного простого сохранения копий полного файла web.config для каждой среды и копирования после сборки)?
Спасибо будет
1 ответ
Я сам не пробовал использовать подход xmlmassupdate для подстановки конфигурации. Но есть альтернативный подход, который заключается в том, чтобы указать каждое обновление конфигурации индивидуально в вашей цели, используя метод XmlFile/UpdateElement, например
<MSBuild.ExtensionPack.Xml.XmlFile
TaskAction="UpdateElement"
File="$(AdminConsoleConfigFilePath)"
XPath="/hibernate-configuration/session-factory/property[@name='connection.connection_string']"
InnerText="Initial Catalog=MyDatabase;Data Source=$(DatabaseServerInstance)"
/>
Затем вы помещаете свои конфигурации в заголовок файла ваших целей, например
<Choose>
<When Condition="$(Environment)=='DEV'">
<PropertyGroup>
<DatabaseServerInstance>DEVSERVER</DatabaseServerInstance>
</PropertyGroup>
</When>
<When Condition="$(Environment)=='QA'">
<PropertyGroup>
<DatabaseServerInstance>QASERVER</DatabaseServerInstance>
</PropertyGroup>
</When>
<When Condition="$(Environment)=='PROD'">
<PropertyGroup>
<DatabaseServerInstance>PRODSERVER</DatabaseServerInstance>
</PropertyGroup>
</When>
</Choose>
Вы также можете поместить блок "Выбрать" в отдельный файл и включить его в файл назначения. Я лично предпочитаю этот подход, потому что он позволил нам централизовать список свойств среды, которые затем могут использоваться несколькими целевыми файлами (например, если у вас есть несколько приложений для развертывания, использующих один и тот же сервер базы данных в каждой среде).