2009-03-25 10 views
12

में पॉलिमॉर्फिज्म मैं एक डब्ल्यूसीएफ सेवा बनाने की सोच रहा हूं जो विभिन्न प्रकारों की एक श्रृंखला को स्टोर/पुनर्प्राप्त कर सकता है। निम्न उदाहरण व्यावहारिक है और यह भी माना जाता स्वीकार्य डिजाइन है:डब्ल्यूसीएफ

[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 विधि में बच्चे प्रकार गुजरती हैं और उन्हें प्राप्त करने में सक्षम होने की आवश्यकता होगी तरीका।

क्या बेहतर विकल्प हैं?

धन्यवाद, रोब

उत्तर

17

आपका उदाहरण संकलन नहीं करेगा क्योंकि इंटरफेस क्षेत्रों को शामिल नहीं कर सकते हैं, जो है क्या ObjectID, StringOne, और StringTwo हैं। आप IObject, IOne, और ITwo के साथ परिभाषित करने का प्रयास कर रहे हैं, एक डेटा अनुबंध है, सेवा अनुबंध नहीं। इस प्रकार, आपको DataContract विशेषता का उपयोग करना चाहिए, न कि ServiceContract विशेषता और कक्षाएं, इंटरफेस नहीं।

[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

क्या डब्ल्यूसीएफ के साथ आपके द्वारा उल्लेख किए गए आईएमएमटीआई इंटरफ़ेस का उपयोग करने का एक ठोस उदाहरण बनाने के लिए यह संभव है? – Kenci

+0

@ मैट डेविस, एक चीज़ की कमी है :) शायद एक्सएमएल का कुछ टुकड़ा? –