2010-01-11 11 views
18

मेरे पास Miguel Castro द्वारा सुझाए गए डब्ल्यूसीएफ सेवाओं की संरचना है। इसका मतलब है कि मैंने सब कुछ मैन्युअल रूप से सेट किया है, और ServiceHost ऑब्जेक्ट्स का उपयोग करके मेरी सेवाओं को होस्ट करने वाला एक कंसोल एप्लिकेशन है।डब्ल्यूसीएफ सेवा के लिए डेटा इंजेक्शन

मैं अपनी सेवा कक्षाओं को पतला रखना चाहता हूं, और वे वर्तमान में व्यवहार कक्षाओं में कॉल पर गुजर रहे हैं। मेरी समस्या अब सर्विस कक्षाओं की जांच इकाई है। मैं कक्षाओं को कुछ रचनाकार पैरामीटर के रूप में इंजेक्ट करना चाहता हूं जैसे कि मैं इसे दूर कर सकता हूं और उचित पृथक इकाई परीक्षण लिख सकता हूं। ServiceHost क्लास तर्क स्वीकार नहीं करता है, इसलिए मेरा सवाल यह है कि मैं सेवा कक्षाओं में डेटा कैसे इंजेक्ट कर सकता हूं - या मैं नहीं कर सकता?

+0

क्या आप आईओसी-कंटेनर का उपयोग कर रहे हैं? और यदि हां कौन सा है? – Fabiano

+0

मैं अभी तक सर्वर पक्ष पर एक आईओसी-कंटेनर का उपयोग नहीं कर रहा हूं। अभी एक परिचय करने की योजना है। क्लाइंट पक्ष पर एकता का उपयोग कर रहा हूं (जैसा कि यह प्रिज्म के साथ आया था), लेकिन सर्वर पर स्ट्रक्चर मैप का उपयोग करने पर विचार करें। वास्तव में किसी के लिए खुला है। आपके उत्तर के लिए – stiank81

उत्तर

29

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

उदाहरण के तौर पर, मैंने हाल ही में एक लिखा है जो सेवा कार्यान्वयन के लिए निर्भरता को तारने के लिए कैसल विंडसर का उपयोग करता है। CreateServiceHost के कार्यान्वयन बस इस करता है:

return new WindsorServiceHost(this.container, serviceType, baseAddresses); 

जहां this.container कॉन्फ़िगर IWindsorContainer है।

public class WindsorServiceHost : ServiceHost 
{ 
    public WindsorServiceHost(IWindsorContainer container, Type serviceType, params Uri[] baseAddresses) 
     : base(serviceType, baseAddresses) 
    { 
     if (container == null) 
     { 
      throw new ArgumentNullException("container"); 
     } 

     foreach (var cd in this.ImplementedContracts.Values) 
     { 
      cd.Behaviors.Add(new WindsorInstanceProvider(container)); 
     } 
    } 
} 

और WindsorInstanceProvider इस तरह दिखता है:

WindsorServiceHost इस तरह दिखता है

public class WindsorInstanceProvider : IInstanceProvider, IContractBehavior 
{ 
    private readonly IWindsorContainer container; 

    public WindsorInstanceProvider(IWindsorContainer container) 
    { 
     if (container == null) 
     { 
      throw new ArgumentNullException("container"); 
     } 

     this.container = container; 
    } 

    #region IInstanceProvider Members 

    public object GetInstance(InstanceContext instanceContext, Message message) 
    { 
     return this.GetInstance(instanceContext); 
    } 

    public object GetInstance(InstanceContext instanceContext) 
    { 
     var serviceType = instanceContext.Host.Description.ServiceType; 
     return this.container.Resolve(serviceType); 
    } 

    public void ReleaseInstance(InstanceContext instanceContext, object instance) 
    { 
     this.container.Release(instance); 
    } 

    #endregion 

    #region IContractBehavior Members 

    public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) 
    { 
    } 

    public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime) 
    { 
    } 

    public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime) 
    { 
     dispatchRuntime.InstanceProvider = this; 
    } 

    public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint) 
    { 
    } 

    #endregion 
} 

यह एक बहुत की तरह लग सकता है, लेकिन लगता है कि यह पुन: प्रयोज्य, सामान्य उद्देश्य कोड है कि एक नहीं बल्कि है कम चक्रीय जटिलता।

आप एक अन्य डी कंटेनर के साथ निर्भरता इंजेक्शन लागू करने या गरीब मैन की डीआई का उपयोग करके उसी कोडिंग मुहावरे का पालन कर सकते हैं।

यहां इस मुहावरे के older writeup है जो गरीब मैन की DI का उपयोग करता है।

+0

Thx। प्रमोशन लग रहा है! कल इसमें खुदाई होगी! – stiank81

+0

बहुत उपयोगी उत्तर। –

+0

डब्ल्यूसीएफ सुविधा का उपयोग करने के बजाय इस दृष्टिकोण का क्या फायदा था ??? – CrazyDart

1

क्या आपने अपनी सेवा को सिंगलटन के रूप में कॉन्फ़िगर किया था? मुझे पता चला कि सेवा उदाहरण बनाने के लिए एक डी कंटेनर का उपयोग करते समय IInstanceProvider कार्यान्वयन समस्याग्रस्त हो सकता है।

5

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

0

लेख Hosting a Mock as a WCF service में एक स्थिर विधि है जो एक एकल अंतराल के साथ विधि में पारित ऑब्जेक्ट के आधार पर डब्ल्यूसीएफ सेवा होस्ट उत्पन्न करेगी।

इस विधि को answer में Recommended patterns for unit testing web services के लिए भी पोस्ट किया गया था।

उपयोग के उदाहरण NSubstitute कहते हैं, लेकिन अन्य मजाकिया freameworks का उपयोग किया जा सकता है।

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