2009-03-25 5 views
12

다양한 유형의 범위를 저장/검색 할 수있는 WCF 서비스를 작성하는 중입니다. 다음 예제 가능한 및 고려 허용 디자인 :WCF의 다형성

[ServiceContract] 
public interface IConnection 
{   
    [OperationContract] 
    IObject RetrieveObject(Guid ObjectID); 

    [OperationContract] 
    Guid StoreObject(IObject NewObject); 


} 

[ServiceContract] 
[ServiceKnownType(IOne)] 
[ServiceKnownType(ITwo)] 
public interface IObject 
{ 
    [DataMember] 
    Guid ObjectID; 

} 

[ServiceContract] 
public interface IOne:IObject 
{ 
    [DataMember] 
    String StringOne; 

} 

[ServiceContract] 
public interface ITwo:IObject 
{ 
    [DataMember] 
    String StringTwo; 

} 

서비스를 사용하는 경우, 나는 RetrieveObject에서 자신의 하위 유형으로 다시를 StoreObject 방법으로 하위 유형을 전달하고받을 수 있어야합니다 방법.

더 좋은 옵션이 있습니까?

감사합니다, 롭 인터페이스 OBJECTID, StringOne 및 StringTwo이 무엇 인 필드를 포함 할 수 없기 때문에 컴파일되지 않습니다

답변

17

귀하의 예. IObject, IOne 및 ITwo로 정의하려는 것은 서비스 계약이 아닌 데이터 계약입니다. 따라서 인터페이스가 아닌 ServiceContract 특성 및 클래스가 아닌 DataContract 특성을 사용해야합니다.

[DataContract] 
[KnownType(typeof(MyOne))] 
[KnownType(typeof(MyTwo))] 
public class MyObject 
{ 
    [DataMember] 
    Guid ObjectID; 
} 
[DataContract] 
public class MyOne : MyObject 
{ 
    [DataMember] 
    String StringOne; 
} 
[DataContract] 
public class MyTwo : MyObject 
{ 
    [DataMember] 
    String StringTwo; 
} 

이들은 인터페이스가 아니라 클래스입니다. DataContract 특성이 ServiceContract 특성을 대체했습니다. KnownType 특성이 ServiceKnownType 특성을 대체했습니다. 이것은 제가 본 것에서보다 정식입니다.

서비스 계약은 다음과 같이 정의된다 :

[ServiceContract] 
public interface IConnection 
{ 
    [OperationContract] 
    [ServiceKnownType(typeof(MyOne))] 
    [ServiceKnownType(typeof(MyTwo))] 
    MyObject RetrieveObject(Guid ObjectID); 

    [OperationContract] 
    [ServiceKnownType(typeof(MyOne))] 
    [ServiceKnownType(typeof(MyTwo))] 
    Guid StoreObject(MyObject NewObject); 
} 

당신은 ServiceKnownType가이 계약의 모든 작업에 적용하도록 (즉,의 ServiceContract 특성 아래) 계약 수준에서 속성을 넣을 수 있습니다.

[ServiceContract] 
[ServiceKnownType(typeof(MyOne))] 
[ServiceKnownType(typeof(MyTwo))] 
public interface IConnection 
{ 
    [OperationContract] 
    MyObject RetrieveObject(Guid ObjectID); 

    [OperationContract] 
    Guid StoreObject(MyObject NewObject); 
} 

당신은 이 같은 데이터 계약에 용도의 인터페이스 할 수 있습니다

interface IEmployee 
{ 
    string FirstName 
    { get; set; } 
    string LastName 
    { get; set; } 
} 
[DataContact] 
class Employee : IEmployee 
{...} 

는 그러나, IEmployee 인터페이스 내 보낸 메타 데이터에 포함되지 않습니다. 따라서 svcutil을 사용하여 프록시 클래스를 생성하면 클라이언트는 IEmployee에 대해 알 수 없습니다. 서비스와 클라이언트가 동일한 응용 프로그램에있는 경우 큰 문제는 아닙니다 (이는 응용 프로그램 도메인간에 통신하는 좋은 방법입니다). 그러나 클라이언트가 서비스와 분리되어 있다면 (압도적 인 경우가 많을 것입니다.) 클라이언트 측에서 IEmployee 인터페이스를 수동으로 복제해야하기 때문에 문제가됩니다.

+0

WCF로 언급 한 IEmployee 인터페이스를 사용하는 구체적인 예를 만들 수 있습니까? – Kenci

+0

@Matt Davis, 한 가지 부족 :) 아마도 xml의 일부분일까요? –