web-dev-qa-db-ja.com

Visual Studioの開発者固有のapp.config / web.configファイル

特定の設定を構成ファイルに保存する.NETプロジェクトがいくつかあります。各開発者は、少し異なる独自の設定ファイルを持っています(ローカルデータベースに接続するための異なる接続文字列、異なるWCFエンドポイントなど)。

現時点では、app/web.configファイルをチェックアウトし、ニーズに合わせて変更する傾向があります。これにより、tfsから最新バージョンを取得するときに、誰かが自分の設定をチェックしたり、カスタム構成を緩めたりすることがあるため、多くの問題が発生します。

私の質問は、このような状況にどのように対処しますか?それとも、この問題はまったくありませんか?

88
twarz01

このページの既存の回答のいくつかを組み合わせたシステムを使用し、さらに Scott Hanselmanによるこの提案 を使用します。

つまり、ここで行った他の回答で示唆されているように、共通のapp.config/web.configを作成し、個々のファイルに特定の設定のほとんどを含めることでした。例えばSMTP設定の場合、app.configには次が含まれます

<system.net>
  <mailSettings>
    <smtp configSource="config\smtp.config" />
  </mailSettings>
</system.net>

このファイルは、ソース管理内のです。ただし、このような個々のファイルは次のとおりではありません。

<?xml version="1.0" encoding="utf-8" ?>
<smtp deliveryMethod="Network">
  <network Host="127.0.0.1" port="25" defaultCredentials="false" password="" userName ="" />
</smtp>

しかし、それだけでは話は終わりません。新しい開発者、または新しいソースのインストールはどうですか?構成の大部分はソース管理に含まれていないため、必要なすべての.configファイルを手動で作成するのは面倒です。少なくともすぐにコンパイルできるソースが欲しいです。

したがって、。config.defaultファイルという名前の.configファイルのバージョンをソース管理に保持します。したがって、新しいソースツリーは次のようになります。

alt text

それでも、Visual Studioにとっては単なる意味のないテキストファイルであるため、開発者にとっては実際には使用できません。したがって、バッチファイルcopy_default_config.bat 、. config.defaultファイルから.configファイルの初期セットを作成します。

@echo off
@REM Makes copies of all .default files without the .default extension, only if it doesn't already exist. Does the same recursively through all child folders.
for /r %%f in (*.default) do (
    if not exist "%%~pnf" (echo Copying %%~pnf.default to %%~pnf & copy "%%f" "%%~pnf" /y)
)
echo Done.

このスクリプトは安全に再実行可能です。すでに.configファイルを持っている開発者は上書きされません。したがって、このバッチファイルをビルド前イベントとして実行することも考えられます。 .defaultファイルの値は、新規インストールに対して正確ではない場合がありますが、妥当な出発点です。

最終的に、各開発者は次のような構成ファイルのフォルダーになります。

alt text

少し複雑に思えるかもしれませんが、開発者がお互いのつま先を踏むのが面倒なので、間違いなく望ましいです。

66
Gavin

Web.configで他のファイルのソースを使用します

<configuration>
    <connectionStrings configSource="ConnectionStrings.config" />
...
</configuration>

Web.configはバージョン管理に保持し、ConnectionStrings.configには使用しないでください。これで、すべての開発者が接続文字列用のファイルを1つ持っています。

これは、ローカルに依存するすべての設定に対して実行できます。

21
fampinheiro

ここでweb.configファイルとVisual Studio 2010のソリューション:

1)Webアプリケーションの.csprojファイルを手動で編集して、次のようなAfterBuildターゲットを追加します。

  <Project>
   ...
    <Target Name="AfterBuild">
      <Copy SourceFiles="web.config" DestinationFiles="obj\$(Configuration)\tempweb.config" />
      <TransformXml Source="obj\$(Configuration)\tempweb.config"
                  Transform="web.$(USERNAME).config"
                  Destination="obj\$(Configuration)\tempweb2.config" />
      <ReadLinesFromFile File="obj\$(Configuration)\tempweb2.config"><Output TaskParameter="Lines" ItemName="TransformedWebConfig"/></ReadLinesFromFile>
      <ReadLinesFromFile File="web.config"><Output TaskParameter="Lines" ItemName="UnTransformedWebConfig"/></ReadLinesFromFile>
      <Copy Condition=" @(UnTransformedWebConfig) != @(TransformedWebConfig) " SourceFiles="obj\$(Configuration)\tempweb2.config" DestinationFiles="web.config" OverwriteReadOnlyFiles="True" />
    </Target>
  </Project>

このターゲットは、ログインしている現在の開発者に対応するWeb.configファイル(したがって、$(USERNAME)変数)を、1)で作成された対応するファイルで変換します。ローカルWeb.configがソース管理されている場合でも、各ビルドでコンテンツが(再起動を回避するために)変更された場合にのみ、ローカルWeb.configを置き換えます。そのため、OverwriteReadOnlyFilesがTrueに設定されます。実際、この点は議論の余地があります。

2)プロジェクトの開発者ごとにWeb.[developer windows login].configという名前のファイルを作成します。 (たとえば、次のスクリーンショットでは、smoとsmo2という名前の2人の開発者がいます):

enter image description here

これらのファイル(開発者ごとに1つ)は、ソース管理できる/すべきです。これらを個別にチェックアウトできるようにするため、メインWeb.configに依存しているとマークしないでください。

この各ファイルは、メインのWeb.Configファイルに適用する変換を表します。変換構文については、 Webアプリケーションプロジェクトの展開のためのWeb.config変換構文 を参照してください。 Visual Studioですぐに使用できるこのクールなXmlファイル変換タスクを再利用します。このタスクの目的は、ファイル全体を上書きするのではなく、mergeXml要素と属性です。

たとえば、Web.configファイルの残りの部分に関係なく、「MyDB」という名前の接続文字列を変更するサンプルweb.[dev login].configは次のとおりです。

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.Microsoft.com/XML-Document-Transform">
    <connectionStrings>
      <add name="MyDB" 
        connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True" 
        xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
    </connectionStrings>
</configuration>

現在、このソリューションは完璧ではありません:

  • ビルド後、開発者はソース管理システムとは異なるWeb.Configをローカルに持つ場合があります
  • ソース管理システムから新しいWeb.Configを取得するときに、ローカル書き込みを強制する必要がある場合があります
  • 開発者はメインのweb.configをチェックアウト/チェックインしないでください。それは少数の人々に予約されるべきです。

ただし、少なくとも、一意のメインweb.configと開発者ごとに1つの変換ファイルを維持するだけで済みます。

WebではなくApp.configファイルに対しても同様のアプローチをとることができますが、これ以上詳しく説明しませんでした。

18
Simon Mourier

環境間でweb.configの違いを避けるために、machine.configを使用しています。

2
Darin Dimitrov

同じ問題があり、私たちがやっていることは

  • Testserver/productionの値でweb.configをチェックインします
  • 開発者はWindowsエクスプローラーに移動し、ファイルの読み取り専用モードを変更します
  • 環境に合わせて構成を編集します。
  • Web.configへのチェックインは、展開値が変更された場合、または構成エントリが追加または削除された場合にのみ行われます。
  • 各開発者が変更する必要があるため、これには各設定エントリに十分なコメントが必要です

ファイルを無視して、チェックインされないようにしましょう。同様の問題に遭遇し、web.configをSubversionの無視リストに追加しました。

ただし、TFSでは少し難しくなります。その方法については この投稿 をご覧ください。

0
Marko

対処できる方法の1つは、トークン化されたシステムを使用し、rakeスクリプトを使用して値を変更することです。

より基本的な方法は、web.configのすべてのAppSettingsのAppSettings.configファイルへのリンクを作成することです(接続と同様)。

<appSettings configSource="_configs/AppSettings.config" />

次に、各開発者のフォルダーにサブフォルダー(/ _configs/dave /)にバージョンがあります。次に、開発者が独自のコードで作業しているときに、サブフォルダーからリンクされたフォルダーのルートにコピーします。

これらのファイルへの変更を伝達することを確認する必要があります(トークン化しない限り)。 AppSettings.configファイルをソース管理の対象から外し、devsの個々のフォルダー(すべて)のみをチェックインすると、正しいフォルダーのコピーが強制されます。

私はトークン化を好みますが、これが簡単な修正を目的としたものである場合、起動して実行するのがより困難になる可能性があります。

0
ArtificialGold

ファイルを無視し、Commom_Web.ConfigとCommon_App.Configを用意します。ビルドサーバーでジョブを実行できるように、これら2つの名前を通常の名前に変更するビルドタスクで継続的統合ビルドサーバーを使用する。

0
Arthis