2009-11-08 16 views
79

बस सोच रहा है कि आप डब्ल्यूसीएफ सेवा से प्रॉक्सी उत्पन्न करना पसंद करेंगे, जब आप चैनलफैक्टरी का उपयोग करके कॉल का आह्वान कर सकते हैं?डब्ल्यूसीएफ चैनलफैक्टरी बनाम प्रॉक्सी

इस तरह आपको प्रॉक्सी उत्पन्न करने और सर्वर को अद्यतन होने पर प्रॉक्सी को पुन: उत्पन्न करने की चिंता करने की आवश्यकता नहीं होगी?

धन्यवाद

उत्तर

82

इसमें 3 बुनियादी तरीके एक WCF ग्राहक बनाने के लिए कर रहे हैं:

  1. दृश्य स्टूडियो आपके प्रॉक्सी उत्पन्न करते हैं। यह ऑटो कोड उत्पन्न करता है जो डब्ल्यूएसडीएल पढ़कर सेवा से जुड़ता है। अगर सेवा किसी भी कारण से बदलती है तो आपको इसे पुन: उत्पन्न करना होगा। इसका बड़ा फायदा यह है कि इसे स्थापित करना आसान है - वीएस में एक जादूगर है और यह सब स्वचालित है। नुकसान यह है कि आप अपने लिए कड़ी मेहनत करने के लिए वीएस पर भरोसा कर रहे हैं, और इसलिए आप नियंत्रण खो देते हैं।

  2. ज्ञात इंटरफ़ेस के साथ ChannelFactory का उपयोग करें। यह आपके पास स्थानीय इंटरफेस रखने पर निर्भर करता है जो सेवा (सेवा अनुबंध) का वर्णन करता है। बड़ा फायदा यह है कि परिवर्तन को और अधिक आसानी से प्रबंधित कर सकते हैं - आपको अभी भी बदलावों को फिर से संकलित करना और ठीक करना होगा, लेकिन अब आप कोड पुन: उत्पन्न नहीं कर रहे हैं, आप नए इंटरफेस का संदर्भ दे रहे हैं। आम तौर पर इसका उपयोग तब किया जाता है जब आप सर्वर और क्लाइंट दोनों को नियंत्रित करते हैं क्योंकि दोनों इकाई परीक्षण के लिए अधिक आसानी से मजाक कर सकते हैं। हालांकि इंटरफेस किसी भी सेवा के लिए लिखा जा सकता है, यहां तक ​​कि आरईएसटी - this Twitter API पर एक नज़र डालें।

  3. अपनी खुद की प्रॉक्सी लिखें - यह HttpClient या WebClient का उपयोग करके, विशेष रूप से आरईएसटी सेवाओं के लिए करना काफी आसान है। यह आपको सबसे अच्छा अनाज नियंत्रण देता है, लेकिन कई एपीआई एपीआई स्ट्रिंग में होने की लागत पर। उदाहरण के लिए: var content = new HttpClient().Get("http://yoursite.com/resource/id").Content; - यदि एपीआई परिवर्तन का विवरण आपको रनटाइम तक कोई त्रुटि नहीं मिलेगी।

व्यक्तिगत रूप से मुझे विकल्प पसंद नहीं आया 1 - ऑटो जेनरेट कोड पर निर्भर गन्दा है और बहुत अधिक नियंत्रण खो देता है। इसके अलावा यह अक्सर क्रमबद्धता के मुद्दों को बनाता है - मैं दो समान वर्गों (सर्वर कोड में से एक, एक ऑटो जेनरेटेड) के साथ समाप्त होता हूं जिसे टाइड किया जा सकता है लेकिन दर्द होता है।

विकल्प 2 सही होना चाहिए, लेकिन चैनल थोड़ा सीमित हैं - उदाहरण के लिए वे completely lose the content of HTTP errors। उस ने कहा कि सेवा का वर्णन करने वाले इंटरफेस रखने और बनाए रखने के लिए कोड करना बहुत आसान है।

+2

@ मुरहाफ नोप - यह उत्तर पूरी तरह से मेरा काम है। मैं हमेशा दूसरों के योगदान की विशेषता देता हूं। मैंने इस जवाब को विभिन्न नौकरियों में .NET में एसओएपी सेवाओं के साथ काम करने के वर्षों के आधार पर लिखा था। वह लेख जो आप लिंक करते हैं, मार्च 2013 से है, जबकि मेरा उत्तर अप्रैल 2010 में लिखा गया था - 3 साल पहले! अगर साहित्य चोरी हुई है तो उसने मुझे कॉपी किया। आरोप लगाने से पहले आपको तिथियों की जांच करनी चाहिए क्योंकि यह करना बहुत आसान है। – Keith

+0

@MurHaf हम भी इसी निष्कर्ष पर नहीं आते हैं - वह लेख प्रॉक्सी (विकल्प 1) को 'सरल' के रूप में स्वत: उत्पन्न करने की अनुशंसा करता है। मैं इसे स्थापित करने में आसान, लेकिन गन्दा और बनाए रखने के लिए दर्द का वर्णन करता हूं। वह अपनी खुद की प्रॉक्सी (विकल्प 3) लिखने पर भी चर्चा नहीं करता है। – Keith

+1

मुझे लगता है कि SvcUtil का भी उल्लेख किया जाना चाहिए, क्योंकि यह क्लाइंट को "लिखने" के सबसे आम तरीकों में से एक है। –

11

खैर आदेश ChannelFactory<T> उपयोग करने के लिए आप सेवा और ग्राहक के बीच अनुबंध विधानसभाओं साझा करने के लिए तैयार रहना चाहिए में। यदि यह आपके साथ ठीक है तो ChannelFactory<T> आपको कुछ समय बचा सकता है।

+2

यह सच नहीं है। –

+0

@ चार्ल्स - क्या आप समझा सकते हैं कि यह सच क्यों नहीं है? –

+5

@Aran: मुझे लगता है कि एंड्रयू का क्या कहना है सही है - कि यदि आप अनुबंध कक्षाओं के फ़ेसिमिलीज़ नहीं बनाना चाहते हैं, तो आपको मूल तक पहुंच की आवश्यकता होगी। यह सच है कि एक तरफ या दूसरे आपको उन अनुबंध वर्गों की आवश्यकता है। आप उन्हें उत्पन्न कर सकते हैं, उन्हें हाथ से लिख सकते हैं, या सेवा स्रोत कोड प्राप्त कर सकते हैं (यदि यह एक ही भाषा में है)। असेंबली साझा करना सबसे आसान तरीका है, लेकिन यह हमेशा संभव नहीं होता है। (हो सकता है कि मैं एंड्रयू को सचमुच ले रहा हूं, लेकिन स्पष्टता यहां महत्वपूर्ण है।) –

8

प्रॉक्सी एसिंक फ़ंक्शन का निर्माण करेगा जिसके लिए अच्छा है।

+2

हां - साथ ही, विजुअल स्टूडियो के "सेवा संदर्भ जोड़ें" के साथ-साथ कमांड लाइन पर svcutil.exe दोनों को आपकी कॉन्फ़िगरेशन को पहचान से परे मार डालो .... कम से कम svcutil.exe के साथ, आप "/ noconfig" को परिभाषित कर सकते हैं स्विच ..... –

+1

चैनलफैक्टरी एसिंक विधियों को भी प्रदान करता है: http://msdn.microsoft.com/en-us/library/ms731177.aspx लेकिन मैं थ्रेडपूल का उपयोग करके एसिंक क्लास बनाने के लिए एक टी 4 टेम्पलेट का उपयोग करना पसंद करता हूं जो करेगा तुल्यकालिक तरीकों का आह्वान करें। – SandRock

+0

टी 4 टेम्पलेट क्या है? – TheWommies

20

मैं मेटाडाटा रीसोल्वर के साथ चैनलफैक्टरी का उपयोग करता हूं। रीसोलव विधि। क्लाइंट कॉन्फ़िगरेशन परेशान है, इसलिए मुझे सर्वर से मेरा ServiceEndpoint मिलता है।

जब आप चैनलफैक्टरी (टी) का उपयोग करते हैं, टी या तो मूल अनुबंध है जिसे आप अपने प्रोजेक्ट या जेनरेट किए गए अनुबंध उदाहरण में संदर्भ से प्राप्त कर सकते हैं। कुछ परियोजनाओं में, मैंने सेवा संदर्भ से कोड जेनरेट किया क्योंकि मैं अनुबंध डीएलएल का संदर्भ नहीं जोड़ सका। आप सेवा संदर्भ के साथ एक एसिंक अनुबंध भी उत्पन्न कर सकते हैं और चैनलफ़ैक्टरी के साथ उस अनुबंध इंटरफ़ेस का उपयोग कर सकते हैं।

मेरे लिए चैनलफैक्टरी का उपयोग करने का मुख्य बिंदु WCF क्लाइंट कॉन्फ़िगरेशन जानकारी से छुटकारा पाना था।नीचे दिए गए नमूना कोड में, आप कॉन्फ़िगर किए बिना डब्लूसीएफ क्लाइंट को कैसे प्राप्त कर सकते हैं।

Dim fixedAddress = "net.tcp://server/service.svc/mex" 
Dim availableBindings = MetadataResolver.Resolve(GetType(ContractAssembly.IContractName), New EndpointAddress(fixedAddress)) 
factoryService = New ChannelFactory(Of ContractAssembly.IContractName)(availableBindings(0)) 
accesService = factoryService.CreateChannel() 

मेरी अंतिम परियोजना में, उपलब्ध बाइंडिंग net.tcp या net.pipe का उपयोग करने के लिए चेक किए जाने पर चेक की जाती है। इस तरह, मैं अपनी जरूरतों के लिए सर्वोत्तम उपलब्ध बाध्यकारी का उपयोग कर सकता हूं। मैं केवल इस तथ्य पर भरोसा करता हूं कि सर्वर पर मेटाडेटा एंडपॉइंट मौजूद है।

मुझे आशा है कि इस मदद करता है

BTW, यह .NET 3.5 का उपयोग कर किया जाता है। हालांकि यह 4.0 के साथ भी काम करता है।

+0

बहुत बढ़िया सामान। मैं MetadataResolver का उपयोग करता हूं। कॉन्फ़िगर के लिए भी रिसाव करें लेकिन मैंने सर्वर से बाध्यकारी को हल करने के बारे में नहीं सोचा था। बहुत अच्छा मुद्दा! –

+0

डब्ल्यूसीएफ क्लाइंट कॉन्फ़िगरेशन से छुटकारा पाने के लिए 'चैनलफैक्टरी का उपयोग करने का मुख्य बिंदु' का उल्लेख करने के लिए उपरोक्त – Kurubaran

7

मेरा उत्तर Keith's और Andrew Hare's उत्तरों का एक सारांश है।

यदि आप सर्वर को नियंत्रित नहीं करते हैं, लेकिन केवल विजुअल स्टूडियो या svcutil का उपयोग कर WSDL/URL- प्रॉक्सी उत्पन्न करते हैं। (ध्यान दें कि जब कभी svcutil बेहतर काम करता है, तो विजुअल स्टूडियो कभी-कभी विफल हो जाता है)।

जब आप सर्वर और क्लाइंट दोनों को नियंत्रित करते हैं, इंटरफ़ेस/अनुबंध साझा करते हैं और चैनलफ़ैक्टरी
पर कॉल करते हैं।

2

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

एक संभावित विकल्प एक प्रीबिल्ड स्क्रिप्ट लिखना संभव हो सकता है जो एसवीसीयूटीटी उपयोगिता को हर बार प्रॉक्सी बनाने के लिए कहता है जब भी आप अपनी परियोजना बनाते हैं, लेकिन फिर भी चैनलफैक्टरी बहुत अधिक स्वच्छ और सुरुचिपूर्ण है।

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