WCF 서비스에서 사용자 정의 유형을 어떻게 반환합니까?
-
22-07-2019 - |
문제
IIS에서 호스팅 된 WCF 서비스가 있습니다. 의도는 고객이 전화를 걸고 다른 프로젝트/DLL에 정의 된 사용자 정의 클래스를받는 것입니다. svcutil.exe를 사용하여 서비스 클라이언트를 생성했습니다. 문제는이자가 생성 클라이언트에 서비스에서 반환하려는 클래스에 대한 새로운 부분 / 프록시 정의가 포함되어 있다는 것입니다. 이제 원래 사용자 정의 클래스와 컴파일 시간에 새로운 부분 정의 사이에 변환 오류가 발생합니다. 그렇다면 WCF 서비스에서 사용자 정의 유형을 어떻게 반환합니까? 조언에 감사드립니다.
해결책
- 예, 공유 DLL에 대한 참조를 추가 할 수 있습니다 (생성 된 프록시 클래스를 사용하지 않고).
- 예, 데이터 계약의 의도를 많이 물리 치고 어떤 종류의 사용자 정의 직렬화가 발생하면 서비스를 연장하는 데 문제가있을 수 있습니다.
나는 전에이 길을 내려 갔고 어떤면에서는 내가하지 않았 으면 좋겠다. RE Extensibility / Custom Serialization- 매우 주의 깊은. 다음과 같은 사전 변경된 직렬 라이저를 사용하면 조금 더 쉽습니다. protobuf-net (WCF에 직접 통합 할 수 있고 확장 성을 염두에두고 설계 될 수 있지만 쉽지는 않습니다.
사실, 하나 이점 수업을 공유하는 것은 테스트하기가 조금 더 쉽다는 것입니다. IFoo
어디에서나, 당신은 그것을 조롱 할 수 있습니다 IFoo
합리적인 성공 기회와 함께. 프록시가 참여할 때 조롱하기가 더 어렵습니다 (테스트 코드와 생산 코드 사이에 더 많은 움직이는 부분을 변경함에 따라).
다른 팁
서비스 호출에서 반환하려는 유형이 DataContract
그런 다음 동일한 어셈블리의 사본을 고객 신청서에 제공하지 않고는 WCF에서 반환 할 수 없습니다.
using System;
using System.ServiceModel;
[ServiceContract]
interface IService
{
[OperationContract]
TimeSpan GetTimeSpan();
}
class Service : IService
{
public TimeSpan GetTimeSpan() { return DateTime.Now.TimeOfDay; }
}
그렇다면 이전 코드가 작동하는 이유는 무엇입니까? 서비스 통화의 양쪽에는 System.dll
그래서 그들은 둘 다 알고 있습니다 System.TimeSpan
OperationContract의 반환 유형 인 유형 GetTimeSpan()
.
다음은 a를 사용하는 예입니다 DataContract
:
using System;
using System.ServiceModel;
using System.Runtime.Serialization;
[ServiceContract]
interface IService
{
[OperationContract]
Contract GetContract();
}
[DataContract]
class Contract
{
[DataMember]
public String MyProperty { get; set; }
}
class Service : IService
{
public Contract GetContract() { return new Contract(); }
}
이제 정의한 클래스에 직렬화 속성을 제공했습니다.Contract
) - 이것은 당신이 사용할 수 있습니다 svcutil.exe
클라이언트 애플리케이션에서 직렬화되어 WCF 서비스로 전송 될 프록시 클래스를 생성합니다.
이제 당신이 아닌 유형을 반환하고 싶다면 DataContract
해당 유형이 포함 된 어셈블리 사본을 클라이언트 응용 프로그램에 제공해야합니다.
발생해야 할 일 중 하나는 사용자가 프록시에 의해 정의 된 클래스가 아닌 DLL의 유형을 사용하도록 서비스 참조를 구성해야한다는 것입니다. http://msdn.microsoft.com/en-us/library/bb628653.aspx
우리는 과거에 그 길을 걸었습니다. 실제로 문제는 물론 이들이 두 가지 수업이므로 @Rich Reuter가 제공 한 링크를 따라야한다는 것입니다.
그러나 우리는 왜 이것이 나쁜 관행인지 어려운 방법을 배웠다.
물론 문제는 어느 시점에서 누군가가 설정 한 "규칙"을 따르는 것이 아니라, 이것을 제안해야 할 큰 이유가 있다는 것입니다. 서비스가 해당 클래스에 다른 필드를 추가 해야하는 경우 다른 클라이언트에 서비스를 제공 해야하는 경우 첫 번째 클라이언트가 영향을받을 수 있습니다. 서비스가 해당 클래스 정의에서 무언가를 변경 해야하는 경우 (다른 클라이언트 서비스를 위해) - 첫 번째 클라이언트에게 다시 영향을 미치고 그 반대도 마찬가지입니다. 클라이언트는 서비스의 수명주기에 영향을 줄 수 있습니다.
대규모 프로젝트에서 이것은 빠르게 유지 보수 부담이됩니다.