2010-05-03 2 views
10

WCF의 ServiceKnownType을 이해하는 데 약간의 문제가 있습니다. WCF의 ServiceKnownType 이해

this blog에서 촬영, 다음 코드는 작동하지 않습니다

[DataContract(Namespace = “http://mycompany.com/”)] 
public class Shape{…} 

[DataContract(Namespace = “http://mycompany.com/”)] 
public class Circle : Shape {…} 

[ServiceContract] 
public interface IMyServer 
{ 
    [OperationContract] 
    bool AddShape(Shape shape); 
} 

합니다.

IMyServer client = new ChannelFactory<IMyServer>(binding, endPoint).CreateChannel(); 

client.AddShape(new Circle()); 

이유는 작동하지 않는 이유는 원을 추가하려하지만 servicecontract가 셰이프 만 허용하기 때문입니다. 당신은 knowntype을 가지고 뭔가를해야만하는데, 어떻게 작동하는지 조금 혼란 스럽습니다.

해당 코드가 서비스 중이므로 왜 서클이 Shape에서 파생되었는지 자동으로 알지 못합니까? 또한 ServiceKnownType은 실제로 무엇을합니까?

ServiceKnownType이 DataContract 아래에 배치되면 분명히 작동합니다. 나는 그것이 헤이 (Hey)를 추측하고 있다고 생각한다. Shape라고 불리는이 특별한 객체 유형은 Circle 일 수도있다. Square와 같은 새로운 유형을 추가하면 ServiceKnownType을 ServiceKnownType에 추가해야하기 때문에 왜 그런 식으로 처리 할 것인지 이해하는 데 어려움을 겪고 있습니다. KnownType을 Shape가 아닌 Square에 두는 것이 유추 할 수 없다면 말이되지 않을까요? 그래서 스퀘어가 이봐, 나 Shape라고 말했어. Shape 클래스를 피우지 않아도 돼? Shape 클래스가 라이브러리에 빌드되어 있고 DiamondShape와 같은 고유 한 모양을 만들려는 경우 소스 코드에 액세스 할 수 없기 때문에 Shape 클래스에 추가 할 수 없습니다.

답변

12

WCF가 모든 어셈블리에 포함되지 않고 가능한 모든 하위 형식 Shape를 찾으려고한다는 점이 문제입니다. 또한 형식 정보 (어셈블리, 정규화 된 형식 이름)를 XML 문서와 함께 전송하지 않습니다.

발신 XML에서 "Circle"태그를 생성하는 데 문제가 없지만 들어오는 deserializater는이 작업을 처리하지 못할 것입니다.

KnownType "해킹"은 양측에서 구현해야하는 알려진 유형의 레지스트리와 같습니다. 그것은 명백합니다. 이 레지스트리에서 디시리얼라이저는 "서클"이 모호하지 않고 파생 된 유형의 모든 사용 가능한 어셈블리 또는 도달 가능한 어셈블리를 구문 분석 할 필요없이 X를 직렬화하도록 deserialize한다는 것을 알고 있습니다.

스퀘어는 "나는 모양"이라고 말하지 않으며 XML 태그로 제공되므로 사용하는 .NET 클래스를 쉽고 자동으로 알지 못합니다.

+0

그래도 해당 서비스의 DataContracts를 검사해야하지 않습니까? 이 예제에는 두 가지만 있고 어쨌든 캐시했을 것입니다. – NibblyPig

+0

아니요, 데이터 계약에서 해당 호출에 대해 실제로 유효한 서브 클래스 또는 존재하는 서브 클래스를 나타내지 않으므로 No입니다. 데이터 계약은 "ok, this는이 속성의 모양"이라고 말하고 "공유의 하위 클래스는 여기에오고 있습니다"라고 말하지 않습니다. – TomTom