2010-06-25 6 views
36

मेरा पहला सवाल तो यह उपयुक्त है आशा:WCF सेवा संदर्भ का अपना अनुबंध इंटरफेस उत्पन्न करता है, पुन: उपयोग नहीं होगा मेरा

साझा इंटरफ़ेस विधानसभा - मैं एक 'साझा' विधानसभा जो एक इंटरफेस है, चलो है की कॉल यह IDocRepository है। यह [ServiceContract] के साथ चिह्नित है और कई [OperationContract]-चिह्नित विधियां हैं।

WCF कार्यान्वयन विधानसभाओं - मैं प्रत्येक साझा विधानसभा संदर्भित दो WCF सेवा परियोजनाओं है, प्रत्येक एक WCF सेवा के रूप में है कि इंटरफ़ेस को लागू करने।

उपभोक्ता असेंबली - अंत में, मेरे पास एक 'क्लाइंट' प्रोजेक्ट है, जो दो डब्ल्यूसीएफ सेवाओं में से प्रत्येक के संदर्भ में साझा असेंबली का भी संदर्भ देता है।

public partial class ExampleClient : System.ServiceModel.ClientBase<SomeNamespace.ExampleSvcRef.IDocRepository>, SomeNamespace.ExampleSvcRef.IDocRepository { 

मैं क्या उम्मीद
मैं आशा व्यक्त की है कि दोनों संदर्भों के बजाय स्वचालित रूप से वारिस होगा:

हालांकि, उपभोक्ता विधानसभा में उत्पन्न सेवा संदर्भ इंटरफेस की एक स्वत: जनरेट संस्करण से निकाले जाते हैं इंटरफ़ेस मैंने परिभाषित किया है कि उपभोक्ता/ग्राहक असेंबली भी संदर्भित कर रहा है। पैरामीटर और रिटर्न प्रकारों के लिए प्रदान की जाने वाली कक्षाओं के पुन: उपयोग की तरह, लेकिन सेवा इंटरफ़ेस के लिए।

क्यों
तो यह है कि मैं या तो सेवा संदर्भ प्रॉक्सी का एक उदाहरण बना सकते हैं और मेरी इंटरफ़ेस प्रकार करने के लिए इसे डाल सकता।

तो मैं हर बार उत्पन्न कोड को संशोधित कर सकता हूं, लेकिन बेहतर तरीका होना चाहिए ...?

(संपादित करें: मैं क्या ज़रूरत है दोनों सेवा संदर्भ के लिए चयनित 'संदर्भित विधानसभाओं में पुन: उपयोग प्रकार' और 'पुन: उपयोग प्रकार के सभी संदर्भित विधानसभाओं में' विकल्प)

उत्तर

44

"संदर्भित असेंबली में पुन: उपयोग प्रकार" केवल आपको डेटा अनुबंधों का पुन: उपयोग करने की अनुमति देता है, न कि सेवा अनुबंध। यदि आप सेवा अनुबंध साझा करना चाहते हैं, तो आपको "सेवा संदर्भ जोड़ें" का उपयोग करने की आवश्यकता नहीं है। आप सीधे ChannelFactory का उपयोग कर सकते हैं।

// Supply the binding and address in code 
Binding binding = new BasicHttpBinding(); 
EndpointAddress address = new EndpointAddress("http://tempuri.org/address"); 
IServiceContract channel = ChannelFactory<IServiceContract>.CreateChannel(binding, address); 

// Or read them from the config file 
ChannelFactory<IServiceContract> channelFactory = new ChannelFactory<IServiceContract>(); 
IServiceContract channel = channelFactory.CreateChannel(); 

चैनल वस्तु भी ICommunicationObject को लागू करेगा, ताकि आप इसे डाल सकता है अगर आप खुला है() या बंद की तरह तरीकों कॉल करने के लिए (की जरूरत है)।

+1

ग्रेट सॉल्यूशन, धन्यवाद –

+0

मैं दूसरे विकल्प के साथ जा रहा था, लेकिन मुझे त्रुटि मिलती है कि एक एंडपॉइंट एड्रेस निर्दिष्ट होना चाहिए। मेरे पास एक ही अनुबंध (इंटरफ़ेस) निर्दिष्ट कॉन्फ़िगरेशन फ़ाइल में एक एंडपॉइंट सेट है, लेकिन ऐसा लगता है कि ऐसा नहीं लगता है? क्या आप मदद कर सकते हैं? –

+2

कभी नहीं; आपको एंडफॉइंट कॉन्फ़िगरेशन नाम को चैनलफ़ैक्टरी <> कन्स्ट्रक्टर में पास करने की आवश्यकता है। –

4

जब आप सेवा संदर्भ बनाते हैं, तो एक बॉक्स आप कर सकते हैं इसे साझा परिभाषाओं का पुन: उपयोग करने के लिए टिकटें। सुनिश्चित करें कि क्लाइंट प्रोजेक्ट पहले ही साझा असेंबली का संदर्भ दे रहा है, फिर से सेवा संदर्भ जोड़ें, और सभी विकल्पों को ध्यान से जांचें।

यदि यह अभी भी काम नहीं करता है, तो आप उपयोग करने वाले बाध्यकारी की जांच करें। मेरे पास एक अस्पष्ट याद है कि मूल HTTP बाध्यकारी प्रकारों के पुन: उपयोग का समर्थन नहीं करेगा?

+0

हाय डेविड, टिप्पणी के लिए धन्यवाद! - मैंने बिल्कुल ऐसा किया है, मुझे उल्लेख करना चाहिए था। :) 'संदर्भित असेंबली में पुन: उपयोग प्रकार' की जांच की गई है, और मैंने मैन्युअल रूप से प्रश्न में असेंबली चुनते समय 'सभी संदर्भित असेंबली में पुन: उपयोग प्रकार' और 'निर्दिष्ट संदर्भित असेंबली में पुन: उपयोग प्रकार' के साथ प्रयास किया है - दोनों एक ही परिणाम के साथ (ऊपरोक्त अनुसार)। –

+0

उस मार्ग के साथ केवल समस्या यह है कि यदि आप एक ही साझा lib के साथ 2 सेवाओं का संदर्भ देना चाहते हैं; आपको डुप्लीकेट ऑब्जेक्ट मिलते हैं। – eschneider

+0

@eschneider - मुझे नहीं लगता कि यह मामला कैसा है, यही कारण है कि 'पुन: उपयोग ...' विकल्प करता है, यह मौजूदा संदर्भित कक्षाओं का उपयोग करके कक्षाओं ('ऑब्जेक्ट्स') के दोहराव को रोकता है - है ना? हालांकि मैं डुप्लीकेट इंटरफेस देख रहा हूं, जो समस्या मैंने अपने प्रश्न में वर्णित की है :)। –

2

एक और अच्छा विकल्प नहीं है, यदि आपने प्रॉक्सी जनरेटर का उपयोग करने के लिए यह सीमित बल्कि कुछ हद तक उपयोगी कार्यक्षमता है के लिए ... एक आंशिक वर्ग का उपयोग जारी रखना चाहते हैं:

namespace <same namespace as generated proxy> 
{ 
    public partial class MyClient : <namespace of "real" service contract>.IServiceContract 
    { 
    } 
} 

सुनिश्चित करें कि प्रॉक्सी है कोड उत्पन्न करना वैसे ही आपका सेवा अनुबंध इसे परिभाषित कर रहा है, यानी, यदि यह 'सूची' का उपयोग कर रहा है, तो सेवा संदर्भ कॉन्फ़िगर करने में उस विकल्प का भी उपयोग करें।दूसरे शब्दों में, सुनिश्चित करें कि आपका जेनरेट किया गया सेवा इंटरफ़ेस आपके वास्तविक सेवा इंटरफ़ेस के बराबर है और उपरोक्त कोड को काम करना चाहिए, और उस संदर्भ को अपडेट करने के लिए जिसका उपयोग आप कोड लिखने के बजाय राइट-क्लिक करते हैं।

+0

एक हैक की तरह लगता है लेकिन काम करता है! –

2

विजुअल स्टूडियो आपके लिए प्रॉक्सी कक्षाएं उत्पन्न करते समय मौजूदा इंटरफ़ेस का पुन: उपयोग करने का समर्थन नहीं करता है। क्वार्टरमेस्टर ने बताया कि पुन: उपयोग प्रकार अनुबंध इंटरफ़ेस का पुन: उपयोग नहीं करेंगे।

हमने इसे विरासत के साथ हल किया है। जेस्टर सॉफ्टवेयर द्वारा सुझाए गए आंशिक वर्ग विचार के समान ही। सिर्फ एक सेवा संदर्भ बनाने के रूप में आप किया होता

अपने ग्राहक की परियोजना में:

यह है कि हम कैसे इसे हल है।

internal class MyServiceProxy : MyServiceClient, MyLogicNamespace.IMyService 
{} 

इस वर्ग उत्पन्न MyServiceClient से विरासत लेकिन यह है कि ग्राहक मूल इंटरफ़ेस को लागू करता है कहता है: फिर एक वर्ग है कि ग्राहक के लिए स्थानापन्न के रूप में कार्य करता है जोड़ें।

MyServiceClient वर्ग किसी भी तरीके कि मूल इंटरफेस के साथ मेल नहीं खाते हैं, तब आप उन्हें जो प्रॉक्सी में जोड़ सकते हैं और में रूपांतरण (मैं आप "ServiceProxies" नाम का फ़ोल्डर में डाल सुझाव है) कोड।

इसके बाद, बस MyServiceProxy का उपयोग करें जहां आपने MyServiceClient का उपयोग किया होगा।

संबंधित मुद्दे