MSBuild Contrib XMLMassUpdate和NHibernate配置

时间:2011-03-30 03:24:26

标签: nhibernate xpath msbuild msbuildcommunitytasks xmlmassupdate

我正在尝试构建一个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>

环境是构建目标所在的名称。在这种情况下,它是“qa”。

我的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属性没有被替换(在上面的代码中,我也永远无法获得配置和替换的结束标记,以便在本网站的编辑器中显示 - 可能是一个火狐问题)。有任何想法吗?我尝试了以下内容:

  1. 从有问题的web.config和替换文件(一起和单独)中删除nhibernate-configuration的名称空间声明。
  2. 为nhibernate声明添加名称空间前缀,并为其添加相关节点和属性前缀。再次,尝试单独或组合使用web.config和替换文件。
  3. 尝试使用MSBuild contrib项目中的最新每晚构建。这不仅不起作用,还打破了其他事情。
  4. 尝试使用基于XPath的xmu:Locator。同时尝试使用和不使用xmu:key值(甚至尝试用xmu:Key替换它)。
  5. 我绝对难过。 XMLMassUpdate是否有用?我们希望将web.config(或至少各种敏感位)的qa和生产版本保留在代码的主体之外,以防我们得到一个初级开发人员或承包商,所以当前的方法是web.qa.config和web.prod.config目前还不可行。关于如何实现这一点的任何想法(除了显而易见的只是保留每个环境的完整web.config的副本并在构建后复制)?

    谢谢, 将

1 个答案:

答案 0 :(得分: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>

您还可以将“选择”块放入单独的文件中,并将其包含在目标文件中。我个人更喜欢这种方法,因为它允许我们集中环境特定属性列表,然后可以由多个目标文件使用(例如,如果您有多个应用程序要在每个环境中使用相同的数据库服务器进行部署)。 / p>