login register Sysop! about ME  
qrcode
    최초 작성일 :    2011년 11월 30일
  최종 수정일 :    2011년 11월 30일
  작성자 :    kobukii
  편집자 :    kobukii (김경균)
  읽음수 :    35,116

강좌 목록으로 돌아가기

필자의 잡담~

이번 강좌는 김경균 MVP가 공유해 준 강좌입니다. 응용 프로그램 배포에 관심이 있는 분들에게는 대단히 유용한 강좌임에 틀림이 없습니다. 블로그는 http://blog.dayofdays.net/ 입니다.

설정파일 변환하기

"더 이상 설정 파일을 매번 변경하지 말자!"

웹 및 윈도우 응용프로그램을 개발할 때 응용프로그램의 각종 설정 정보를 저장하기 위해 설정 파일을 사용합니다. 이 설정 파일은 데이터베이스 연결 문자열, 디버그 설정, 인증, 권한, 파일 서버의 경로와 같은 응용프로그램에 필요한 설정 정보를 저장하게 됩니다. 간단히 나열하긴 했지만 실제 환경에서의 설정 파일은 상당히 복잡하게 구성되어있는 경우가 허다합니다. 여러분이 지금 개발중인 응용프로그램이 아주 간단한 테스트용 프로그램이 아니라 실 운영을 목적으로 하는 프로그램이라면 최소한 로컬 PC와 운영 서버가 필요하게 됩니다. 로컬 PC와 운영 서버의 환경이 100% 동일할 수 없기 때문에 설정 파일 또한 서로 다를 확률이 아주 높습니다. 단 두 대의 컴퓨터라면 수동으로 설정 파일을 변경할 수도 있겠지만 개발 및 운영환경이 로컬 PC, 개발 서버, 테스트 서버, 스테이징 서버, 운영 서버로 구성되어 있다면 수동으로 설정 파일을 관리하는 것은 스트레스 그 자체일 것입니다.

이를 해결하기 위해 ASP.NET 4.0에서는 설정 파일 변환기능(Configuration Transformation)을 제공하고 있습니다. 사실 설정 파일 변환기능은 ASP.NET 4.0의 기능이라기 보다는 Visual Studio 2010의 기능입니다. 이것이 뭐가 중요하냐 라고 생각할 수 도 있지만 Visual Studio 2010의 기능이기 할 수 있는 일이 더 많아진다는… 여기까지 궁금증을 유발 시키고, 이 글의 중반부에서 다시 설명 드리겠습니다.^^

Web.confg 변환하기

우선 웹 프로젝트에서 설정파일을 변환하는 기능에 대해 알아보도록 하겠습니다. 다음은 일반적으로 볼 수 있는 Web.config 파일입니다.

Web.config
  1. <?xml version="1.0"?>
  2. <configuration>
  3.   <connectionStrings>
  4.     <add name="DatabaseConnection" connectionString="ConnectionString"/>
  5.   </connectionStrings>
  6. </configuration>

아래에 있는 두 설정 파일은 진짜 설정파일이 아니라 Web.config 파일이 배포될 때 어떻게 변해야 할지를 지정하는 XML 파일에 불과합니다. 구문을 간단히 살펴보면 변환 설정은 XML-Document-Transform 네임스페이스에 정의된 XML 특성을 사용하여 지정하게 되며 이 네임스페이스는 xdt Prefix에 매핑 됩니다. 이어서 나오는 connectionString 요소는 Web.config와 동일하지만 Transform 어트리뷰트와 Locator 어트리뷰트가 더 있는 것을 볼 수 있습니다.

Locator는 자신에 할당된 값에 해당하는 요소를 선택하며 Transform은 Locator가 선택한 요소에 대해 수행할 작업을 지정하게 됩니다. 좀더 자세히 살펴보면 xdt:Locator=”Match(name)”은 Web.config 파일에서 name 어트리뷰트가 “DatabaseConnection”인 요소를 찾습니다. 그 다음 xdt:Transform의 SetAttributes를 통해 변환 파일에 설정되어 있는 모든 어트리뷰트를 Locator가 선택한 요소에 적용하게 되는 것입니다. SetAttributes에는 매개변수를 지정할 수 있는데 콤마(,)를 구분 자로 하여 어트리뷰트 이름을 전달할 수 있습니다. “SetAttributes(connectionString)”처럼 작성하게 되면 지정된 어트리뷰트에 해당하는 값만을 업데이트 하게 됩니다.

다음은 위의 구문을 사용하여 생성한 설정 변환 파일입니다.

Web.Debug.config
  1. <?xml version="1.0"?>
  2. <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  3.   <connectionStrings>
  4.     <add name="DatabaseConnection"
  5.       connectionString="DebugConnectionString"
  6.       xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
  7.   </connectionStrings>
  8. </configuration>

Web.config와 동일하나 connectionString의 값이 DebugConnectionString입니다.

Web.Release.config
  1. <?xml version="1.0"?>
  2. <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  3.   <connectionStrings>
  4.     <add name="DatabaseConnection"
  5.       connectionString="ReleaseConnectionString"
  6.       xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
  7.   </connectionStrings>
  8. </configuration>

Web.config와 동일하나 connectionString의 값이 ReleaseConnectionString입니다.

설정파일 변환에 대한 자세한 정보는 http://msdn.microsoft.com/ko-kr/library/dd465326.aspx를 참고 하세요.

변환 파일 생성이 완료되었으므로 배포를 통해 파일이 변환되는지 확인해 보도록 하겠습니다. 프로젝트의 컨텍스트 메뉴에서 [Publish] 메뉴를 선택하여 웹 게시를 수행합니다. 웹 게시 대화상자에서 게시 방식을 File System으로 설정하고 적절한 폴더를 선택한 다음 게시를 수행합니다. File System으로 설정하는 이유는 그냥 테스트가 쉽도록 하기 위함입니다.


Figure 1 One-Click 배포 대화상자

One-Click 배포에 관한 자세한 정보는 http://msdn.microsoft.com/ko-kr/library/dd465337.aspx를 참고 하세요.

이상 없이 배포가 완료되었으면 배포 경로에 Web.config 파일이 있는 것을 볼 수 있으며 이 파일을 편집기를 통해 확인해 보면 connectionString이 ReleasConnectionString으로 변경된 것을 확인할 수 있습니다. 솔루션 구성(Solution Configuration)을 Debug로 변경한 다음 다시 One-Click 배포를 수행하면 connectionString의 값이 DebugConnectionString로 변경되는 것을 확인할 수 있습니다.

설정 파일 변환에 의해 생성된 Web.config
  1. <?xml version="1.0"?>
  2. <configuration>
  3.   <connectionStrings>
  4.     <add name="DatabaseConnection" connectionString="ReleaseConnectionString"/>
  5.   </connectionStrings>
  6. </configuration>

설정파일 변환에 대해서 알아 봤으니 이제 우리의 실 개발환경에서 어떻게 활용하면 좋을까에 대해 고민해 보겠습니다. 지금 진행중인 프로젝트의 서버 구성이 로컬 pc, 개발서버, 스테이징 서버, 운영서버로 구성되어 있다고 가정하면, 각 서버에서 사용하는 DB 연결 문자열과 파일 서버의 경로가 모두 다를 경우 각 서버에 배포할 때마다 해당되는 값들을 수작업으로 변경해야 합니다. 이런 불편하고 비 합리적인 작업을 해결하기 위해 설정 파일 변환이 나온 것이며 이를 실제로 적용해 보도록 하겠습니다.

먼저 솔루션 구성(Solution Configuration)을 추가합니다. [Build] -> [Configuration Manager]를 선택하면 Configuration Manager 대화상자가 표시되며 여기서 Active solution configuration 콤보 박스의 <New…> 항목을 선택합니다.


Figure 2 새로운 솔루션 구성 생성

그러면 New Solution Configuration 대화상자가 표시되며 Name 텍스트 박스에 개발서버를 나타내는 Development를 입력하고 설정을 복사해올 대상을 Debug로 선택합니다. 이렇게 하는 이유는 기본 설정을 Debug에서 상속 받겠다는 것이고 추가적인 사항만 변경하겠다는 의미입니다. 또한 개발 서버는 운영환경이 아닌 개발환경이므로 Debug의 설정 내용을 복사하는 것입니다.


Figure 3 새 솔루션 구성 대화상자

<New…>를 선택하여 스테이징 서버를 의미하는 Staging과 실 운영 서버를 의미하는 Operation을 추가합니다. 이 두 설정은 운영환경이므로 Release로부터 설정 정보를 복사하도록 합니다.

설정 추가가 완료되면 Web.config 파일에서 마우스 오른쪽 버튼을 클릭하여 [Add Config Transform]이라는 메뉴를 선택합니다. 이 메뉴는 솔루션 구성(Solution Configuration)에 추가된 모든 항목에 대해 변환파일을 생성해 줍니다.


Figure 4 설정파일 변환 자동 생성

변환 파일이 모두 생성되면 솔루션 탐색기의 Web.config는 다음처럼 구성됩니다. 간단하고 멋지지 않습니까? 마지막으로 추가된 변환 파일에 DB 연결 문자열과 파일 서버의 경로를 변경해 주고 저장합니다.


Figure 5 생성된 변환 파일들

이제 모든 준비가 완료되었습니다. 오늘은 스테이징 서버에 배포를 하는 날입니다. 솔루션 구성(Solution Configuration)을 Staging로 변경하고 One-Click 배포를 수행하기만 하면 추가 작업 없이 설정 파일이 변경되고 배포가 완료됩니다.


Figure 6 솔루션 구성 선택

App.config 변환하기

일반 응용프로그램(Console, WinForm, WPF 등)도 설정 파일이 변환이 가능할까? 기본적으로는 안 됩니다. 안 되는데 뭣 하러 이 글을 쓰는 것일까? 기본적으로 안 되는 것이지 불가능한 것은 아닙니다. 기본적으로 안되지만 불가능하지 않다는 것은 아무래도 웹 프로젝트에서 보다 조금 번거로운 작업이 있다는 것을 의미합니다. 그래도 많이 어렵거나 번거롭지는 않습니다. 매번 설정 파일을 변경하는 것 보다는…

그렇다면 어떻게 가능한 것일까? 서두에서 꺼내다 만 이야기가 있습니다. 설정 파일 변환은ASP.NET 4.0이 제공하는 것이 아니라 Visual Studio 2010이 제공하는 기능이라고. 고로 Visual Studio 2010을 사용하기만 하면 어떤 설정파일이던 모두 변환할 수 있다는 말입니다.

여기서는 콘솔 응용프로그램을 사용합니다. WinForm, WPF 모두 동일합니다. 파일 변환 기능은 프로젝트 파일이 어떻게 구성되어 있느냐에 따라 결정됩니다. 일단 아래의 코드를 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 설정 이후에 추가 합니다.

설정 파일 변환을 가능하게 하기 위한 XML
  1. <UsingTask TaskName="TransformXml" AssemblyFile="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.Tasks.dll" />
  2. <Target Name="AfterCompile" Condition="exists('app.$(Configuration).config')">
  3.   <TransformXml Source="app.config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="app.$(Configuration).config" />
  4.   <ItemGroup>
  5.     <AppConfigWithTargetPath Remove="app.config" />
  6.     <AppConfigWithTargetPath Include="$(IntermediateOutputPath)$(TargetFileName).config">
  7.       <TargetPath>$(TargetFileName).config</TargetPath>
  8.     </AppConfigWithTargetPath>
  9.   </ItemGroup>
  10. </Target>

빌드 시 Microsoft.Web.Publishing.Tasks.dll 어셈블리를 사용하여 파일 변환을 수행합니다. app.config을 소스로 하고 app.솔루션구성.config 파일 즉, app.debug.config 같은 파일을 변환 파일로 사용하여 변환을 하게 됩니다.

Note : 프로젝트 파일은 프로젝트 언로드(Unload)이후에 편집할 수 있습니다.

프로젝트 파일을 변경하였으면 추가 적인 솔루션 구성(Solution Configuration)을 추가 합니다. 여기서는 test 설정 하나만 더 추가 하였습니다. 그 다음 변환 파일을 추가하기 위해 app.config에서 마우스 오른쪽 버튼을 클릭하여 [Add Config Transform]를 선택하려고 하면 [Add Config Transform] 메뉴가 없다는 것을 알게 될 것입니다. 아쉽게도 이 기능은 Web 프로젝트에서만 제공되는 것 같습니다. 자동으로 안되면 어떻게 할까요? 그냥 수동으로 추가해 버리면 그만입니다.

수동으로 app.debug.config, app.release.config, app.test.config를 추가 합니다. 자 이제 빌드를 위한 모든 준비가 완료 되었습니다. 솔루션 구성(Solution Configuration)을 test로 하고 빌드를 수행한 다음 출력 폴더의 ConsoleEx.exe.config(콘솔 프로젝트의 실행 파일 명이 ConsoleEx.exe임)을 확인해 보면 설정 파일 변환이 정상적으로 동작 했음을 볼 수 있습니다.

번 외로 진정한 개발자라면 깔끔한 코드와, 들여쓰기, 단 하나의 경고도 무시할 수 없는 깐깐함에 더해 멋진 솔루션 구성도 생각해 볼 수 있습니다. 앞에서 만든 프로젝트 구조를 살펴보면 다음처럼 설정파일이 웹 프로젝트와는 다르게 모두 나열되어 있는 것을 볼 수 있습니다.


Figure 7 정리되지 않은 설정 파일들

설정 파일을 변환하는 데는 아무런 문제도 되지 않지만 성격상!! 이를 고쳐 볼까 합니다. 간단합니다. 다시 한번 프로젝트 파일을 언로드(Unload)하고 파일을 열어보면 설정파일이 있는 ItemGroup이 다음처럼 구성된 것을 볼 수 있습니다.

변경 전 app.config
  1. <ItemGroup>
  2.   <None Include="app.config" />
  3.   <None Include="app.debug.config"/>
  4.   <None Include="app.release.config"/>
  5.   <None Include="app.test.config"/>
  6. </ItemGroup>

여기서 ItemGroup의 각 하위 요소에 다음 코드처럼 <DependentUpon>App.config</DependentUpon>와 같은 자식 요소를 추가하면 Web 프로젝트의 설정 파일처럼 깔끔하게 하위 노드로 들어가게 됩니다. DependentUpon 요소는 지정된 요소에 의존하는 구조로 구성된다는 의미 입니다.

변경 후 app.config
  1. <ItemGroup>
  2.   <None Include="app.config" />
  3.   <None Include="app.debug.config">
  4.     <DependentUpon>App.config</DependentUpon>
  5.   </None>
  6.   <None Include="app.release.config">
  7.     <DependentUpon>App.config</DependentUpon>
  8.   </None>
  9.   <None Include="app.test.config">
  10.     <DependentUpon>App.config</DependentUpon>
  11.   </None>
  12. </ItemGroup>


Figure 8 깔끔하게 정리된 설정 파일들

그다지 중요하지 않아 보일지는 몰라도 이런 습관을 들이는 건 썩 훌륭한 습관이지 않나 하는 생각을 해 봅니다. 아니면 말고..

지금까지 닷넷 응용프로그램에서 설정 파일을 변환하는 방법에 대해 알아 봤습니다. 최초 한번의 고생으로 배포 때 마다 행복할 수 있다면 상당히 훌륭하고 편리한 기능이라고 생각됩니다. 귀찮아 말고 적용해 보면 생각 보다 좋다는 것을 느낄 수 있을 것입니다.

더 이상 매번 설정 파일을 변경하지 말자!


authored by

  taeyo
  2011-11-30(14:24)
캐릭 이미지
아주 맘에 드는 내용입니다~
배포 패키지를 테스트 서버용, 운영 서버용, 개발 서버용으로
각각 따로 만들때 매우 유용할 듯 합니다.

  khs3141
  2011-11-30(14:43)
아주 유용한 내용이네요~
좋은 내용 감사합니다.

  goni0607
  2011-11-30(21:21)
캐릭 이미지
좋은 강좌 감사합니다~ ^^
아... 저도 어여 2008에서 벗어나야 할텐데요... /한숨/

  violeter33
  2011-12-01(17:43)
캐릭 이미지
와우 ^^ 감솨
  itist
  2011-12-05(09:34)
캐릭 이미지
굿굿굿!
  lscjhet
  2012-01-16(13:26)
캐릭 이미지
와우....반은 알겠고 반은 모르겟네요....ㅎㅎ
어쩃든 굿굿굿!!!...멋지세요 ㅠ

  yangga96
  2012-03-19(11:13)
혹시 Embedded Resource 도 이런 형태로 사용할 수 있나요??
  yangga96
  2012-03-22(16:09)
자답 입니다.
BeforeBuild로 아주 쉽게 되네요.


 
 
.NET과 Java 동영상 기반의 교육사이트

로딩 중입니다...

서버 프레임워크 지원 : NeoDEEX
based on ASP.NET 3.5
Creative Commons License
{5}
{2} 읽음   :{3} ({4})