Visual Studio의 개발자 별 app.config / web.config 파일
구성 파일에 특정 설정을 저장하는 여러 .NET 프로젝트가 있습니다. 이제 각 개발자는 약간 다른 자체 구성 파일을 갖게됩니다 (로컬 db에 연결하기위한 다른 연결 문자열, 다른 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>
Keep the web.config in version control and don't do it for ConnectionStrings.config. Now all developers have one file for the connection string.
You can do this for all the settings that are local dependant.
Here a solution for web.config files and Visual Studio 2010:
1) Edit manually your web application .csproj file to add an AfterBuild
Target like this:
<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>
This target will transform the Web.config file corresponding to the current developer logged in - hence the $(USERNAME)
variable -, with the corresponding file created in 1). It will replace the local Web.config only if the content has changed (to avoid restart) at each build, even if the local Web.config is source controlled, that's why there is the OverwriteReadOnlyFiles
is set to True. This point in fact is arguable.
2) Create a file named Web.[developer windows login].config
for each developer in the project. (for example in the following screenshots I have two developers named smo and smo2):
These files (1 per developer) can/should be source-controlled. They should not be marked as dependent on the main Web.config because we want to be able to check them out individually.
Each of this file represent a transformation to apply to the main Web.Config file. The transformation syntax is described here: Web.config Transformation Syntax for Web Application Project Deployment. We reuse this cool Xml file transformation task that comes out-of-the-box with Visual Studio. The purpose of this task is merge Xml elements and attributes instead of overwriting the whole file.
For example, here is a sample web.[dev login].config
that changes a connection string named 'MyDB', regardless of the rest of the Web.config file:
<?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>
Now, this solution is not perfect because:
- after building, developers may have a different Web.Config locally than in the source control system
- they may have to force local write when getting a new Web.Config from the source control system
- developers should not check out/in the main web.config. It should be reserved to few people.
But at least, you only have to maintain a unique main web.config plus one transformation file per developer.
A similar approach could be taken for App.config (not web) files but I did not elaborate further.
We are using machine.config to avoid having differences in web.config between the environments.
How about ignoring the file, so it never gets checked in? I've run into a similar issue and have added web.config to the ignore list in Subversion.
In TFS though, it's a little bit harder, see this post on how to do it.
One way you could cope is to have a tokenised system and use a rake script to change the values.
A more rudimentary method could be to have a link to an AppSettings.config file for all AppSettings in your web.config (similar with connections) i.e.
<appSettings configSource="_configs/AppSettings.config" />
Then have a folder with each of your developers have a version in a sub folder (i.e. /_configs/dave/). Then when a developer is working on their own code they copy from the sub folder to the root of the linked folder.
You will need to make sure you communicate changes to these files (unless you tokenise). If you keep the AppSettings.config file out of source control and only check in the devs individual folders (all of them) then they will be forced to copy the correct one.
I prefer tokenisation but can be tougher to get up and running if this is only meant to be a quick fix.
Ignore the files and have a Commom_Web.Config and Common_App.Config. Using a continuous integration build server with build tasks which rename these two to normal names so that the build server can do its job.
We have the same problem and what we are doing is
- Check in the web.config with testserver / production values
- Developer goes to windows explorer and change the read only mode of the file
- Edit the config to suit to their environment.
- Check in into the web.config happens only when deployment values changes or any config entry is added or deleted.
- This needs a good amount of comment for each config entry as it needs to be changed by each dev
Assuming you are using Visual Studio, why don't you use different Solution Configurations? For example: you can have a Debug config which uses Web.config.debug and a Release config which uses Web.config.release. Web.config.debug should have something like
<appSettings file="C:/Standard_Path_To_Configs/Standard_Name_For_Config.config">
with the file Standard_Name_For_Config.config that gots all the personal developer settings, while the Web.config.release always has the production settings. You can store default configs in some source controlled folder and make a new user take them from there.
'program story' 카테고리의 다른 글
브라우저 확대 / 축소 수준 변경 (0) | 2020.09.08 |
---|---|
Android의 JNI에서 SIGSEGV (세분화 오류)를 포착하고 스택 추적을 얻으려면 어떻게해야합니까? (0) | 2020.09.08 |
Ido 모드가 너무 똑똑합니다. 파일 이름을 완성하지 못하도록 할 수 있습니까? (0) | 2020.09.08 |
HTML5 (0) | 2020.09.08 |
INNER JOIN 조건에 'OR'이있는 것이 나쁜 생각입니까? (0) | 2020.09.08 |