WCF ChannelFactory बनाम प्रॉक्सी का निर्माण


82

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

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

धन्यवाद


हमेशा ChannelFactory का उपयोग करें। मैं इसे पर्याप्त रूप से नहीं बता सकता।
टॉम

जवाबों:


88

WCF क्लाइंट बनाने के 3 मूल तरीके हैं:

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

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

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

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

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


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

@MurHaf हम भी एक ही निष्कर्ष पर नहीं आते हैं - यह आलेख ऑटो-जेनरेट करने की सलाह देता है एक प्रॉक्सी (विकल्प 1) को 'साधारण' के रूप में। मैं इसे स्थापित करने के लिए आसान है, लेकिन गड़बड़ और बनाए रखने के लिए एक दर्द का वर्णन करता हूं। वह आपके स्वयं के प्रॉक्सी (विकल्प 3) को लिखने पर भी चर्चा नहीं करता है।
कीथ

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

21

मैं MetadataResolver.Resolve विधि के साथ ChannelFactory का उपयोग करता हूं। क्लाइंट कॉन्फ़िगरेशन एक परेशान है, इसलिए मैं सर्वर से अपना ServiceEndpoint प्राप्त करता हूं।

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

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


गज़ब की चीज़ें। मैं MetadataResolver.Resolve को कॉन्फ़िगर करने के लिए उपयोग करता हूं, लेकिन मैंने सर्वर से बाइंडिंग को हल करने के बारे में नहीं सोचा था। बहुत अच्छी बात!
स्लीपर स्मिथ

उल्लेख के लिए upvoteThe main point of using ChannelFactory to get rid of the WCF client config
कुरुबरन

11

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


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

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

2
@Charles ठीक है, इसलिए आप कह रहे हैं कि आप ChannelFactory <T> का उपयोग कर सकते हैं, भले ही आपके पास T के इंटरफ़ेस को हाथ से कोड करने और फिर उसका उपयोग करके विधानसभाओं तक कोई पहुंच न हो।
अरन मुलहोलैंड

1
@Aran: हाँ, या तो हाथ से कोडिंग करके या svcutil जैसे उपकरण का उपयोग करके (यह मानते हुए कि सेवा चल रही है और सुलभ है)।
Igby Largeman

9

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


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

1
ChannelFactory भी async मेथड प्रदान करता है: msdn.microsoft.com/en-us/library/ms731177.aspx लेकिन मैं थ्रेडपूल का उपयोग करके एक async क्लास बनाने के लिए एक T4 टेम्पलेट का उपयोग करना पसंद करता हूं जो सिंक्रोनस तरीकों को आमंत्रित करेगा।
सैंडरॉक

1
अद्यतन के रूप में: .NET 4.5 ChannelFactory <T> कार्य-आधारित अतुल्यकालिक कार्यों का भी समर्थन करता है।
जिम्पफ

8

मेरा उत्तर कीथ और एंड्रयू हरे के उत्तरों का सारांश है।

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

जब आप सर्वर और क्लाइंट दोनों को नियंत्रित करते हैं, तो इंटरफेस / कॉन्ट्रैक्ट साझा करें और ChannelFactory को कॉल करें


2

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

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.