성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
글쓰기
제목
이름
암호
전자우편
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'>VS.NET 2008 - 서비스 참조 시 기존 데이터 컨테이너 DLL 사용</div><br /> <br /> VS.NET 2008에 이 기능이 있다는 것을 처음 알게 되었던 때가 지난 3월에 있었던 "Microsoft Global Summit" 행사에서였습니다. 지금도 기억이 나는군요. ^^ 강사가 이 기능을 설명했을 때, 박수 소리가 제법 터져나왔었던.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 우선, 이 문제에 대한 "VS.NET 2005"에서의 문제점을 짚고 넘어가는 것이 이해에 도움이 될 듯하니, 설명을 좀 해보겠습니다. <br /> <br /> <pre class='code'> 솔루션 구조. ClassLibrary1: 클래스 라이브러리 프로젝트 - Entity 클래스가 정의되어 있음 WebService1: ASP.NET 웹 서비스 프로젝트 - ClassLibrary1 프로젝트를 참조해서 사용 WindowsFormsApplication1: WinForm 프로젝트 - ClassLibrary1, WebService1를 참조해서 사용. </pre> <br /> 예를 들어, 다음과 같은 정의를 담고 있는 ClassLibrary1 프로젝트가 있고,<br /> <br /> <pre class='code'> public class <b>MyClass</b> { public string Name; public int Age; } </pre> <br /> 또한, 이를 사용하는 웹 메서드가 담긴 WebService1 프로젝트가 있고,<br /> <br /> <pre class='code'> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service1 : System.Web.Services.WebService { [WebMethod] public <b>MyClass</b> GetData() { MyClass mc = new MyClass(); mc.Age = 15; mc.Name = "Data"; return mc; } } </pre> <br /> 이런 상황에서, WindowsFormsApplication1이라는 프로젝트에서 WebService1을 참조하려고 하면 다음과 같은 식으로 네임스페이스를 기재하게 됩니다.<br /> <br /> <img alt='vsnet2008_reuse_class_lib_1.png' src='/SysWebRes/bbs/vsnet2008_reuse_class_lib_1.png' /><br /> <br /> <br /> 문제는?<br /> "WindowsFormsApplication1" 프로젝트에서는 ClassLibrary1 프로젝트를 참조하여 기존 Entity 관련 클래스를 사용하고 있음에도 불구하고, WebService1를 참조하면서 네임스페이스만 다른 별도의 클래스 정의들을 포함하게 된다는 점입니다.<br /> <br /> 즉, 다음과 같은 경우이지요.<br /> <br /> <pre class='code'> localhost.Service1 svc = new localhost.Service1(); <b>localhost.MyClass</b> cls = svc.GetData(); <b>ClassLibrary1.MyClass</b> org = new ClassLibrary1.MyClass(); // 웹 메서드로부터 받은 데이터 구조를 ClassLibrary1을 사용하는 메서드들에 넘겨주기 위해 // 데이터 복사 <b>org.Name = cls.Name; org.Age = cls.Age;</b> </pre> <br /> <hr style='width: 50%' /><br /> <br /> 참고로, VS.NET 2005에서 위와 같은 상황을 해결하려면 몇 가지 우회 방법을 선택해야만 합니다.<br /> <br /> <ol> <li>클래스 정의를 담고 있는 프로젝트를 직접 참조하지 않고, "웹 참조"로부터 생성된 클래스들을 사용하도록 구성.</li> <li>웹 참조로 생성될 클래스들에 대해, 별도의 처리를 해주는 클라이언트 측 <a target='_tab' href='/2/0/338'>schemaImporterExtension</a>을 등록.</li> </ol> <br /> 1번 방법이 나름대로 괜찮습니다. 실제로, 저 같은 경우에 XSD를 정의한 후, 그 스키마 대로 Entity 클래스 코드를 자동 생성한 다음 (Dummy일지언정) Web Service 메서드를 통해 클라이언트에서 가져갈 수 있도록 노출시키는 방법을 사용하곤 했습니다.<br /> <br /> 반면 2번 방법은, 해당 사항에 대해서 알고/이해하고 있는 개발자도 드물 뿐더러, 역시나 코딩이 들어가기 때문에 그다지 쉽게 제공되는 방법은 아닙니다.<br /> <br /> 자,,, 그런데 VS.NET 2008에 와서는 위와 같은 우회 방법이 필요 없게 되었습니다. (제 생각에는 아마도, 위의 2번 방법과 같은 처리를 해주는 공통 라이브러리를 기본 제공해 주는 방식을 통해 해결을 해주는 것 같습니다.)<br /> <br /> 어떻게 해결해 주는지... 한번 볼까요? ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> 지금은 기억이 희미하지만, 예전 Summit에서 봤었던 예제는 ASP.NET 웹 서비스에 대한 것으로 기억납니다. 제가 방법을 모르는 것인지, 아직 VS.NET 2008에 버그가 있는지는 모르겠지만, 아쉽게도 현재 이 기능이 WCF 서비스/클라이언트에 대해서는 잘 동작하지만 웹 서비스 참조에서는 동작하지 않았습니다. (하지만, "웹 서비스 참조"가 서비스 참조 대화상자로 통합된 것으로 봐서는 정식 버전이 나오면 웹 서비스에 대해서 이 기능이 동작할 것으로 예상됩니다.)<br /> <br /> 예를 들기 위해, <a target='_tab' href='/2/0/522'>WCF 클래스 라이브러리를 VS.NET 2008에서 생성</a>합니다. 그다음, WindowsFormsApplication1 프로젝트에서 해당 클래스 라이브러리를 서비스 참조합니다. 이 과정에서 전에는 없었던 새로운 옵션이 보이게 됩니다.<br /> <br /> <img alt='vsnet2008_reuse_class_lib_2.png' src='/SysWebRes/bbs/vsnet2008_reuse_class_lib_2.png' /><br /> <br /> "Advanced..." 버튼을 누르면 다음과 같은 화면이 나옵니다.<br /> <br /> <img alt='vsnet2008_reuse_class_lib_3.png' src='/SysWebRes/bbs/vsnet2008_reuse_class_lib_3.png' /><br /> <br /> 오... 딱 나왔군요. ^^ 현재 참조된 모든 DLL들에서 "서비스 참조 시 포함하게 되는 클래스"들과 동일한 정의를 포함하고 있는 경우 별도로 생성하지 않고 재사용하게 됩니다. 그래서 (당연한 이야기지만), 클라이언트 측의 코드도 다음과 같이 간결하게 구성이 됩니다.<br /> <br /> <pre class='code'> Service1Client wcf = new Service1Client(); <b>ClassLibrary1.MyClass</b> cls = wcf.GetData(); // cls 클래스 직접 사용. </pre> <br /> 실제로 생성되는 Proxy 클래스(Reference.cs)의 코드 자체가 아래와 같이, "ClassLibrary1"의 네임스페이스를 사용하게 됩니다.<br /> <br /> <pre class='code'> [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] public partial class Service1Client : System.ServiceModel.ClientBase<WindowsFormsApplication1.ServiceReference.IService1>, WindowsFormsApplication1.ServiceReference.IService1 { public Service1Client() { } // 중간 생략 // <b>public ClassLibrary1.Class1T HelloWorld() { return base.Channel.HelloWorld(); } public ClassLibrary1.MyClass GetData() { return base.Channel.GetData();</b> } } </pre> <br /> 이런 이유 때문에, 저 같은 경우 현재 VS.NET 2005를 사용하여 진행되고 있는 프로젝트에서 <a target='_tab' href='/2/0/495'>"Orcas와 VS.NET 2005의 혼합 개발"</a> 방법으로 WCF 부분의 서비스 참조를 VS.NET 2008을 이용해서 프록시 코드를 생성시키는 방식으로 유용하게 사용하고 있습니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> [내용추가: 2007-08-31]<br /> <br /> 좀 더 테스트 한 결과, XML Web Service의 참조에 대해서만 데이터 컨테이너 DLL을 재활용할 수 없다기 보다는, XmlSerializer를 사용하는 모든 경우에 그런 현상이 발생하는 것을 확인했습니다. 즉, WCF 서비스 조차도 XmlSerializer 를 사용한다면 동일하게 WSDL에 의해 배포되는 타입 정보가 내려오게 됩니다.<br /> <br /> 어쨌든, 이 부분은 프록시 코드를 생성해내는 svcutil.exe 내부에서 수정이 필요할 것 같습니다. <br /> <br /><br /><hr /><span style='color: Maroon'>[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1510
(왼쪽의 숫자를 입력해야 합니다.)