1

MSBuildファイルを作成して、複数のWebサイトのセットを複数の環境に展開しようとしています。現時点では、プロジェクトをビルドして、ディレクトリにダンプしています。

変数$(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. MSBuildcontribプロジェクトからの最新のナイトリービルドを使用しようとしました。これはうまくいかなかっただけでなく、他のことも壊しました。
  4. XPathベースのxmu:Locatorを使用してみました。また、xmu:key値を使用する場合と使用しない場合の両方を試しました(さらに、xmu:Keyに置き換えてみました)。

私は絶対に困惑しています。XMLMassUpdateはまったく機能しますか?ジュニア開発者または請負業者を受け入れる場合に備えて、web.configのqaバージョンと製品バージョン(または少なくともさまざまな機密ビット)をコードの本体から除外したいので、現在の方法はweb.qa.configとweb.prod.configは、現時点では実際には実行可能ではありません。これを実装する方法について何か考えはありますか(各環境の完全なweb.configのコピーを保持し、ビルド後にコピーするという明白なもの以外に)?

ありがとう、ウィル

4

1 に答える 1

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>

「選択」ブロックを別のファイルに入れて、ターゲット ファイルから含めることもできます。私は個人的にこのアプローチを好みます。これにより、環境固有のプロパティのリストを一元化でき、複数のターゲット ファイルで使用できるようになるからです (たとえば、各環境で同じデータベース サーバーを使用する複数のアプリケーションを展開する場合)。

于 2011-04-02T02:39:05.303 に答える