2009-03-25 6 views
12

Tôi đang xem xét việc xây dựng một dịch vụ WCF có thể lưu trữ/truy xuất một loạt các loại khác nhau. là ví dụ sau đây hoàn toàn khả thi và cũng được coi là thiết kế có thể chấp nhận:Đa hình trong 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; 

} 

Khi sử dụng dịch vụ, tôi sẽ cần để có thể vượt qua các loại con vào phương pháp StoreObject và nhận được chúng trở lại như kiểu trẻ em của họ từ RetrieveObject phương pháp.

Có các tùy chọn nào tốt hơn không?

Cảm ơn, Rob

Trả lời

17

dụ của bạn sẽ không biên dịch vì giao diện không thể chứa các lĩnh vực, đó là những gì ObjectId, StringOne, và StringTwo đang có. Những gì bạn đang cố gắng để xác định với IObject, IOne, và ITwo là một hợp đồng dữ liệu, không phải là một hợp đồng dịch vụ. Như vậy, bạn nên sử dụng thuộc tính DataContract, không phải thuộc tính ServiceContract và các lớp, không phải là các giao diện.

[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; 
} 

Lưu ý rằng đây là các lớp chứ không phải giao diện. Thuộc tính DataContract đã thay thế thuộc tính ServiceContract. Thuộc tính KnownType đã thay thế thuộc tính ServiceKnownType. Điều này là kinh điển hơn từ những gì tôi đã nhìn thấy.

hợp đồng dịch vụ của bạn sau đó sẽ được xác định như thế này:

[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); 
} 

Bạn có thể đặt các ServiceKnownType thuộc tính ở cấp hợp đồng (ví dụ, bên dưới thuộc tính ServiceContract) để có nó áp dụng cho tất cả các hoạt động của hợp đồng.

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

    [OperationContract] 
    Guid StoreObject(MyObject NewObject); 
} 

Bạn thể giao diện sử dụng trong hợp đồng dữ liệu của bạn như thế này:

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

Tuy nhiên, giao diện IEmployee không được bao gồm trong siêu dữ liệu xuất khẩu. Vì vậy, nếu bạn sử dụng svcutil để tạo ra các lớp proxy của bạn, khách hàng của bạn sẽ không biết về IEmployee. Đây không phải là một vấn đề lớn nếu dịch vụ và khách hàng của bạn cư trú trong cùng một ứng dụng (đó là cách tốt để giao tiếp giữa các miền ứng dụng). Tuy nhiên, nếu khách hàng của bạn tách biệt với dịch vụ của bạn (trong phần lớn các trường hợp, nó sẽ là), điều này trở nên có vấn đề bởi vì bạn sẽ phải nhân đôi giao diện IEmployee ở phía máy khách theo cách thủ công.

+0

Có possbile để bạn có thể làm cho một ví dụ cụ thể về cách sử dụng giao diện IEmployee bạn đề cập, với WCF? – Kenci

+0

@Matt Davis, một điều là thiếu :) Có lẽ một số phần của xml? –