MSBuild Contrib XMLMassUpdate 和 NHibernate 配置

发布于 2024-10-27 07:36:50 字数 3525 浏览 8 评论 0原文

我正在尝试构建一个 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 属性没有被替换(在上面的代码中,我也永远无法获取配置和的结束标记)替换显示在本网站的编辑器中 - 可能是 Firefox 问题)。有什么想法吗?我已尝试以下操作:

  1. 从相关 web.config 和替换文件(一起和单独)中删除 nhibernate-configuration 的命名空间声明。
  2. 在 nhibernate 声明中添加命名空间前缀,并用它作为相关节点和属性的前缀。再次单独或组合尝试 web.config 和替换文件。
  3. 尝试使用 MSBuild contrib 项目中的最新夜间构建。这不仅不起作用,还破坏了其他东西。
  4. 尝试使用基于 XPath 的 xmu:Locator。还尝试了使用和不使用 xmu:key 值(甚至尝试将其替换为 xmu:Key)。

我完全被难住了。 XMLMassUpdate 真的有用吗?我们希望将 web.config 的质量保证和生产版本(或至少是各种敏感位)保留在代码主体之外,以防我们有初级开发人员或承包商加入,因此当前的方法web.qa.config 和 web.prod.config 目前还不太可行。关于如何实现这一点有什么想法(除了为每个环境保留完整 web.config 的副本并在构建后复制的明显方法之外)?

谢谢, 将要

I'm attempting to build up an MSBuild file to deploy a set of several websites to multiple environments. At the moment, I've built the project and have it dumped into a directory.

I'm using the variable $(AdminConsoleConfigFilePath) to refer to the path of the web.config file in this directory. My substitutions file is denoted by the variable $(AdminConsoleConfigReplacementFile). I've set up the following task in my msbuild file for the project:

<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"/>

`

The values of the other variables here are declared as follows:

<ConfigurationContentReplacementXPathRoot>/configuration</ConfigurationContentReplacementXPathRoot>
<SubstitutionsXPathRoot>/configuration/substitutions/$(Environment)</SubstitutionsXPathRoot>

Environment is the name of where the build is targeted. In this case, it's "qa".

My web.config has the typical hibernate-config section as follows:

<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>

My replacements file looks like the following:

<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>

Now, the connection.connection_string property is not being replaced (in the above code, I also could never get the closing tags for configuration and substitution to show in the editor on this site - might be a firefox issue). Any ideas? I've tried the following:

  1. removing the namespace declaration for nhibernate-configuration from the web.config in question and the replacement file (both together and individually).
  2. Adding a namespace prefix to the nhibernate declaration and prefixing the relevant nodes and attributes with it. Again, tried on both the web.config and the replacement file, both individually and in combination.
  3. Attempted to use the latest nightly build from the MSBuild contrib project. Not only did this not work, it broke other things as well.
  4. Tried using an XPath-based xmu:Locator. Also tried both with and without the xmu:key value (and even tried replacing it with xmu:Key).

I'm absolutely stumped. Does the XMLMassUpdate thing work at all? We'd like to keep the qa and production versions of the web.config (or at least the various sensitive bits) out of the main body of the code in case we get a junior dev or contractor in, so the current method of the web.qa.config and web.prod.config isn't really viable at this point. Any thoughts on how to implement this (besides the obvious one of just keeping copies of the full web.config for each environment and copying over after the build)?

Thanks,
Will

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

关于从前 2024-11-03 07:36:50

我自己还没有尝试使用 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>

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

I haven't tried using the xmlmassupdate approach to configuration substitution myself. But there is an alternate approach which is to specify each configuration update individually in your target using the XmlFile/UpdateElement method, e.g.

    <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)" 
    />

You then put your configurations in the header of your targets file, e.g.

<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>

You can also put the "Choose" block into a separate file and include it from your targets file. I personally prefer this approach because it has allowed us to centralise the list of environment-specific properties, which can then be used by multiple targets files (e.g. if you have multiple applications to deploy that use the same database server in each environment).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文