Sunday, December 1, 2013

Modifying NHibernate Connection String Value from MSBUILD file.

I am a big proponent of using Team City and MSBuild to create automated deployments in to Development, Testing and Staging environments.

I recently came across a problem with modifying a standard NHibernate connection string value using MSBuild and MSBuild Extension Pack, the MSBuild Extension Pack provides a collection of over 480 MSBuild Tasks, MSBuild Loggers and MSBuild Task Factories.

A typical NHibernate configuration setting looks like the following:


<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.MsSqlCeDialect</property>
<property name="connection.driver_class">NHibernate.Driver.SqlServerCeDriver</property>
<property name="connection.connection_string">Data Source=FirstSample.sdf</property>
</session-factory>
</hibernate-configuration>
The section we want to change is

<property name="connection.connection_string">Data Source=FirstSample.sdf</property>
My first attempt was to use the XPath query of

/configuration/hibernate-configuration/session-factory/property[@name='connection.connection_string']
This was not matching the app.config XML which perplexed me at first until it dawned on me to use the namespace value of "urn:nhibernate-configuration-2.2".

The XMLFile class contains a namespace node

<Target Name="MakeWebConfig">
<ItemGroup>
<Namespaces Include="Mynamespace">
<Prefix>x</Prefix>
<Uri>urn:nhibernate-configuration-2.2</Uri>
</Namespaces>
</ItemGroup>
<MSBuild.ExtensionPack.Xml.XmlFile
TaskAction="UpdateElement"
File="%(BuildArtifactsDirWebConfig.FullPath)"
XPath="/configuration/x:hibernate-configuration/x:session-factory/x:property[@name='connection.connection_string']"
InnerText="$(KimHelperConnectionString)"
Namespaces="@(Namespaces)"
/>
</Target>
view raw MakeAppConfig hosted with ❤ by GitHub

By setting the Namespaces value in the ItemGroup and then referencing it using @(Namespaces) in the Namespaces attribute of the XMLFile class I was able to get the desired result.