[c#] Visual Studio의 개발자 별 app.config / web.config 파일

구성 파일에 특정 설정을 저장하는 여러 .NET 프로젝트가 있습니다.

이제 각 개발자는 조금씩 다른 자체 구성 파일을 갖게됩니다 (로컬 데이터베이스에 연결하기위한 다른 연결 문자열, 다른 WCF 끝점 등).

현재 우리는 app / web.config 파일을 확인하고 필요에 맞게 수정하는 경향이 있습니다.

이로 인해 TFS 에서 최신 버전을 가져올 때 때때로 누군가가 자신의 설정을 확인하거나 사용자 지정 구성이 느슨해지기 때문에 많은 문제가 발생 합니다.

이와 같은 상황을 어떻게 처리합니까? 아니면이 문제가 전혀 없습니까?



답변

우리는이 페이지에있는 몇 가지 기존 답변과 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 파일 버전을 유지 합니다. 따라서 새로운 소스 트리는 다음과 같습니다.

대체 텍스트

그래도 개발자에게는 아무런 소용이 없습니다. 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 파일의 값은 새 설치에 대해 정확하지 않을 수 있지만 합리적인 시작점입니다.

궁극적으로 각 개발자는 다음과 같은 구성 파일 폴더가 있습니다.

대체 텍스트

약간 복잡해 보일 수 있지만 개발자가 서로의 발가락을 밟는 번거 로움보다는 확실히 낫습니다.


답변

Web.config에서 다른 파일의 소스 사용

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

web.config를 버전 제어에 유지하고 ConnectionStrings.config에 대해 수행하지 마십시오. 이제 모든 개발자가 연결 문자열에 대해 하나의 파일을 갖게됩니다.

로컬 종속적 인 모든 설정에 대해이 작업을 수행 할 수 있습니다.


답변

다음은 web.config 파일 및 Visual Studio 2010에 대한 솔루션입니다.

1) 웹 애플리케이션 .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>

이 대상은 현재 로그인 한 개발자 (따라서 $(USERNAME)변수) 에 해당하는 Web.config 파일 을 1)에서 생성 된 해당 파일로 변환합니다. 로컬 Web.config가 소스로 제어되는 경우에도 각 빌드에서 콘텐츠가 변경된 경우에만 (다시 시작을 방지하기 위해) 로컬 Web.config를 대체합니다. OverwriteReadOnlyFiles True로 설정된 입니다. 사실이 점은 논쟁의 여지가 있습니다.

2) Web.[developer windows login].config프로젝트의 각 개발자 이름이 지정된 파일을 만듭니다 . (예를 들어 다음 스크린 샷에는 smo 및 smo2라는 두 명의 개발자가 있습니다.)

여기에 이미지 설명 입력

이러한 파일 (개발자 당 1 개)은 소스로 제어 할 수 있거나 제어해야합니다. 개별적으로 체크 아웃 할 수 있기 때문에 기본 Web.config에 종속 된 것으로 표시해서는 안됩니다.

이 파일 각각은 기본 Web.Config 파일에 적용 할 변환을 나타냅니다. 변환 구문은 웹 응용 프로그램 프로젝트 배포를위한 Web.config 변환 구문에서 설명합니다 . Visual Studio와 함께 기본 제공되는이 멋진 Xml 파일 변환 작업을 재사용합니다. 이 작업의 목적은 전체 파일을 덮어 쓰는 대신 Xml 요소와 특성을 병합 하는 것입니다.

예를 들어 다음은 web.[dev login].config나머지 Web.config 파일에 관계없이 ‘MyDB’라는 연결 문자열을 변경 하는 샘플 입니다.

<?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와 하나의 변환 파일 만 유지하면됩니다.

App.config (웹이 아님) 파일에 대해서도 유사한 접근 방식을 사용할 수 있지만 더 자세히 설명하지는 않았습니다.


답변

환경 간 web.config의 차이를 피하기 위해 machine.config를 사용하고 있습니다.


답변

파일을 무시하여 체크인되지 않도록하는 것은 어떻습니까? 비슷한 문제가 발생하여 Subversion의 무시 목록에 web.config를 추가했습니다.

하지만 TFS에서는 조금 더 어렵 습니다. 방법에 대한 이 게시물 을 참조하십시오 .


답변

대처할 수있는 한 가지 방법은 토큰 화 된 시스템을 보유하고 rake 스크립트를 사용하여 값을 변경하는 것입니다.

좀 더 기본적인 방법은 web.config (연결과 유사)의 모든 AppSettings에 대한 AppSettings.config 파일에 대한 링크를 포함하는 것입니다.

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

그런 다음 각 개발자의 폴더가 하위 폴더 (예 : / _configs / dave /)에 버전을 갖도록합니다. 그런 다음 개발자가 자신의 코드를 작업 할 때 하위 폴더에서 링크 된 폴더의 루트로 복사합니다.

토큰 화하지 않는 한 이러한 파일에 대한 변경 사항을 전달해야합니다. AppSettings.config 파일을 소스 제어에서 제외하고 devs 개별 폴더 (모두) 만 체크인하면 올바른 폴더를 복사해야합니다.

나는 토큰 화를 선호하지만 이것이 빠른 수정을위한 것이라면 시작하고 실행하기가 더 어려울 수 있습니다.


답변

파일을 무시하고 Commom_Web.Config 및 Common_App.Config가 있습니다. 빌드 서버가 작업을 수행 할 수 있도록이 두 가지 이름을 일반 이름으로 바꾸는 빌드 태스크와 함께 지속적 통합 빌드 서버를 사용합니다.