MSBuild Contrib XMLMassUpdate和NHibernate配置

MSBuild Contrib XMLMassUpdate和NHibernate配置,nhibernate,xpath,msbuild,msbuildcommunitytasks,xmlmassupdate,Nhibernate,Xpath,Msbuild,Msbuildcommunitytasks,Xmlmassupdate,我正在尝试构建一个MSBuild文件,以便将一组多个网站部署到多个环境中。目前,我已经构建了该项目,并将其转储到一个目录中 我使用变量$(AdminConsoleConfigFilePath)来引用此目录中web.config文件的路径。我的替换文件由变量$(AdminConsoleConfigReplacementFile)表示。我已在项目的msbuild文件中设置了以下任务: <Target Name="AdminConsoleConfig" DependsOnTargets="Bui

我正在尝试构建一个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>
<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>
/配置
/配置/替换/$(环境)
环境是生成的目标位置的名称。在这种情况下,它是“qa”

My web.config具有典型的hibernate配置部分,如下所示:

<ConfigurationContentReplacementXPathRoot>/configuration</ConfigurationContentReplacementXPathRoot>
<SubstitutionsXPathRoot>/configuration/substitutions/$(Environment)</SubstitutionsXPathRoot>
<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>

NHibernate.Connection.DriverConnectionProvider
重新提交
NHibernate.dialogue.mssql2005dialogue
NHibernate.Driver.SqlClientDriver
[修订]
假的
真的
网状物
250
NHibernate.ByteCode.Castle.proxyFactory,NHibernate.ByteCode.Castle
我的替换文件如下所示:

<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的问题)。有什么想法吗?我尝试了以下方法:

<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>
  • 从相关web.config和替换文件中删除nhibernate配置的名称空间声明(一起或单独)
  • 向nhibernate声明添加名称空间前缀,并使用它作为相关节点和属性的前缀。再次在web.config和替换文件上分别或组合进行了尝试
  • 试图使用MSBuild contrib项目中最新的夜间生成。这不仅不起作用,还破坏了其他东西
  • 尝试使用基于XPath的xmu:Locator。还尝试了使用和不使用xmu:key值(甚至尝试用xmu:key替换它)
  • 我完全被难住了。XMLMassUpdate的东西能工作吗?我们希望将web.config的qa和生产版本(或至少各种敏感位)保留在代码的主体之外,以防有初级开发人员或承包商加入,因此目前web.qa.config和web.prod.config的方法在这一点上并不可行。关于如何实现这一点,有什么想法吗(除了为每个环境保留完整web.config的副本并在构建后复制之外)

    谢谢,
    Will

    我自己还没有尝试过使用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>
    
    
    开发服务器
    QASERVER
    PRODSERVER
    

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

    我自己还没有尝试过使用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>
    
    
    开发服务器
    QASERVER
    PRODSERVER
    
    您还可以将“Choose”块放入单独的文件中,并将其从目标文件中包含。我个人更喜欢这种方法,因为它允许我们集中环境特定属性的列表,然后可以由多个目标文件使用(例如,如果要部署的多个应用程序在每个环境中使用相同的数据库服务器)