성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Java - How to use the Foreign Funct...
[정성태] 제가 큰 실수를 했군요. ^^; Delegate를 통한 Bein...
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <br /> <div class='mainCenterTitle'>XmlSerializer 생성자의 실행 속도를 올리는 방법 - 두 번째 이야기</div><br /> <br /> 우선, 이 글을 읽으시기 전에 문맥의 이해를 돕기 위해 다음의 토픽을 먼저 읽어주십시오.<br /> <br /> <pre class='code'> XmlSerializer 생성자의 실행 속도를 올리는 방법 ; <a target='_tab' href='/2/0/511'>http://www.sysnet.pe.kr/2/0/511</a> </pre> <br /> 참고로, 오늘 이야기는 "MSBuild"와 함께 진행됩니다. 이 부분에서... 벌써 "아하... 어떤 내용인지 알겠다" 하실 분이 있을 것 같군요. ^^ 어쨌든, MSBuild에 대한 이해가 부족하신 분들은 다음의 토픽을 미리 읽어두시는 것도 좋겠습니다.<br /> <br /> <pre class='code'> Inside MSBuild ; <a target='_tab' href='https://learn.microsoft.com/en-us/archive/msdn-magazine/2006/june/msdn-magazine-june-2006'>https://learn.microsoft.com/en-us/archive/msdn-magazine/2006/june/msdn-magazine-june-2006</a> </pre> <br /> <hr style='width: 50%' /><br /> <br /> 지난 토픽을 보신 분들은, sgen.exe로 생성된 "[파일명].XmlSerializers.dll"과 같은 형식을 어디선가 본 적이 있으실 것입니다. 어디였을까??? <br /> <br /> 명확한 재현 예를 들어볼까요? ^^<br /> <br /> 우선, "Class Library" 형식의 프로젝트를 하나 만든 후 다음과 같은 정의를 포함하는 "Class1.cs" 파일을 추가합니다.<br /> <br /> <pre class='code'> using System; using System.Collections.Generic; using System.Text; namespace ClassLibrary1 { public class MyClass { public string Prop; } } </pre> <br /> 다음, 위의 MyClass 타입을 반환하는 아래의 코드와 같은 웹 메서드를 구현한 웹 애플리케이션을 만듭니다.<br /> <br /> <pre class='code'> [WebMethod] public MyClass GetData() { return new MyClass(); } </pre> <br /> 이제 간단한 독립실행형 응용 프로그램 프로젝트(Console 또는 WinForm)를 만들어서 위의 웹 서비스를 참조한 다음, <b>"Debug" 모드가 아닌, "Release" 모드로</b> 빌드를 합니다.<br /> <br /> 아래는 제가 테스트 한 "XmlSerializerTest" 프로젝트의 빌드 결과물이 있는 bin\release 폴더의 내용입니다. <br /> <br /> <pre class='code'> XmlSerializerTest.exe XmlSerializerTest.exe.config XmlSerializerTest.pdb XmlSerializerTest.vshost.exe XmlSerializerTest.vshost.exe.config <b>XmlSerializerTest.XmlSerializers.dll</b> </pre> <br /> 보시는 것처럼, "[파일명].XmlSerializers.dll"이 자동으로 생성된 것을 확인할 수 있습니다. 이 때문에, 웹 서비스를 참조한 프로젝트를 Release 모드로 빌드해서 배포하는 경우에는 "XmlSerializer" 내부에서 "System.IO.FileNotFoundException" 예외가 발생하지 않게 됩니다.<br /> <br /> Visual Studio IDE에서는, 위의 Sgen.exe 결과물이 생성되지 않도록 하는 옵션도 제공해 줍니다. 아래와 같이 "Generate serialization assembly" 옵션을 "Off"로 주면 됩니다.<br /> <br /> <img alt='sgen_msbuild_task_use_1.png' src='/SysWebRes/bbs/sgen_msbuild_task_use_1.png' /><br /> <br /> <hr style='width: 50%' /><br /> <br /> 특이한 점이 있다면, "[파일명].XmlSerializers.dll"의 자동 생성은 "웹 서비스 참조"에 한해서 발생할 뿐, 위의 예제에서 응용 프로그램이 "MyClass"가 정의된 DLL을 직접 참조해서 XmlSerializer를 이용하는 경우에는 자동 생성되지 않습니다. (이 이유에 대해서는 잠시 후에 답이 나옵니다.)<br /> <br /> 어쨌든, 이쯤 되면 답은 거의 나온 것이나 다름없습니다.<br /> 왜냐하면, VS.NET 2005 역시 MSBuild로 빌드를 하는 것이기 때문에 틀림없이 그 안에 sgen.exe가 동작되도록 하는 그 무엇인가 있을 것이기 때문입니다.<br /> <br /> 이를 위해, 자신의 빌드 옵션에서 불려지는 아래와 같은 "Microsoft.Common.targets" 파일들 중의 하나를 열어서 살펴보면 해답을 발견할 수 있습니다. (물론, 변경까지 하게 되면 모든 프로젝트의 빌드에 영향을 줄 수 있습니다.)<br /> <br /> <pre class='code'> "C:\Windows\Microsoft.NET\Framework\v2.0.50727\Microsoft.Common.targets" "C:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets" "C:\Windows\Microsoft.NET\Framework64\v2.0.50727\Microsoft.Common.targets" "C:\Windows\Microsoft.NET\Framework64\v3.5\Microsoft.Common.targets" </pre> <br /> 찾아낸 내용은 다음과 같습니다.<br /> <br /> <pre class='code'> <SGen BuildAssemblyName="$(TargetFileName)" BuildAssemblyPath="$(IntermediateOutputPath)" References="@(ReferencePath)" ShouldGenerateSerializer="true" <b>UseProxyTypes="true"</b> KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" ToolPath="$(SGenToolPath)"> <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly"/> </SGen> </pre> <br /> 보시면, "UseProxyTypes" 옵션이 "true"로 되어 있는 것을 확인할 수 있는데요. 바로 이 옵션 떄문에 "웹 서비스 참조"에 대해서만 "[파일명].XmlSerializers.dll" 파일들이 생성되는 것입니다. 간단하게는, 이 옵션을 "false"로 바꿔주면 모든 참조 DLL 들에 대해서 "SerializationAssembly"를 얻을 수 있습니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 하지만 개인적으로는, 위와 같은 방법을 선호하지는 않습니다. 왜냐하면, 팀 개발에서 모든 구성원에게 "Microsoft.Common.targets" 파일을 변경하라고 하는 것은 그다지 바람직하지 않기 때문입니다. 하긴, 이런 부분은 "빌드 서버"에만 적용하면 된다는 현실적인 이유로 인해 묵인될 수는 있습니다.<br /> <br /> 하지만, 또 다른 이유로, 쓸데없는 타입들에 대해서도 sgen 작업이 이뤄진다는 점을 들 수 있습니다. 사실, 설계가 잘된 솔루션 구조라면 특정 라이브러리 프로젝트에 모든 데이터 엔티티 클래스들이 구현되어져 있을 것이므로 해당 프로젝트에만 적용하는 것이 더 바람직하다고 봅니다.<br /> <br /> 그렇다면, 프로젝트 파일을 수정해야 할 텐데요. 이에 대해서는 다음의 토픽을 간단하게 살펴 보십시오.<br /> <br /> <pre class='code'> Do you know: editing VS project files made easy ; <a target='_tab' href='https://learn.microsoft.com/en-us/archive/blogs/nagarajp/do-you-know-editing-vs-project-files-made-easy'>https://learn.microsoft.com/en-us/archive/blogs/nagarajp/do-you-know-editing-vs-project-files-made-easy</a> </pre> <br /> 그럼, 우리가 원하는 데로 해볼까요? ^^<br /> 저라면, 다음과 같이 추가를 하겠습니다. ^^<br /> <br /> <pre class='code'> <Target Name="AfterBuild"> <SGen BuildAssemblyName="$(TargetFileName)" <b>BuildAssemblyPath="$(OutputPath)"</b> References="@(ReferencePath)" ShouldGenerateSerializer="true" KeyContainer="$(KeyContainerName)" KeyFile="$(KeyOriginatorFile)" DelaySign="$(DelaySign)" <b>UseProxyTypes="false"</b> ToolPath="$(SGenToolPath)"> <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly"/> </SGen> </Target> </pre> <br /> 이제 빌드를 해보면, 해당 DLL 에 대해서 "[파일명].XmlSerializers.dll"이 생성되는 것을 확인할 수 있습니다. 이 부분에서... "에이, 그 정도는 '빌드 후 이벤트' 기능으로도 얼마든지 구현이 가능한데!"라고 하시는 분이 계실지도 모르겠는데요. MSBuild의 장점은, 해당 DLL 프로젝트를 다른 프로젝트가 참조할 때 발생합니다. ^^<br /> <br /> 다른 프로젝트에 의해서 참조되는 경우, 해당 DLL만 복사되는 것이 아니라 자동적으로 "[파일명].XmlSerializers.dll"까지 복사되어 넘어갑니다. 우와~~~ ^^; (게다가 빌드 이벤트는 "TFS 팀 빌드" 시에는 효과가 없다는 점도 있지요.)<br /> <br /> 이제 배우셨으니, 여러분들의 클래스 라이브러리에 적용해 보십시오. 이전보다 "쪼끔 더" 빠른 초기 실행 속도를 경험하실 수 있습니다. (디버그 모드에서 실행시, System.IO.FileNotFoundException 예외가 발생하면서 동적 DLL들이 생성되는 경우가 있는지 확인해 보시면 됩니다. 하나도 발생하지 않도록 만드는 순간,,, 가벼운 희열을 느끼실 수 있습니다. ^^;)<br /> <br /> 마지막으로 아래는, 위의 내용과 비슷한 내용을 담고 있는 해외 블로거의 글입니다.<br /> <br /> <pre class='code'> VS2005 - When SGEN Doesn't Work... ; <a target='_tab' href='http://www.kiwidude.com/blog/2007/02/vs2005-when-sgen-doesnt-work.html'>http://www.kiwidude.com/blog/2007/02/vs2005-when-sgen-doesnt-work.html</a> </pre> <br /> <br /> <br /><br /><hr /><span style='color: Maroon'>[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
9230
(왼쪽의 숫자를 입력해야 합니다.)