2012-09-10 7 views
17

निर्भरता मैं वर्तमान में निम्नलिखित कोड का उपयोग कर रहा ले जाने क्या कथन का उपयोग करने के लिए होता है:जब मैं इंजेक्शन

public class MyProvider 
{ 
    public MyProvider() 
    { 
    } 

    public void Fetch() 
    { 
     using (PopClient popClient = new PopClient()) 
     { 
      .... 
     } 
    } 
} 

क्योंकि मैं इस तथ्य की वजह विधि प्राप्त करें और इकाई परीक्षण करने में सक्षम होना चाहता हूँ कि मैं कर सकते हैं ' टी मॉक पॉप क्लाइंट, मैंने एक इंटरफेस और एक रैपर क्लास बनाया जो पॉप क्लाइंट में कॉल करता है। मेरे अद्यतन कोड लगता है:

public class MyProvider 
{ 
    private readonly IPopClient popClient; 

    public MyProvider(IPopClient popClient) 
    { 
     this.popClient = popClient; 
    } 

    public void Fetch() 
    { 
     using (var pop3 = popClient) 
     { 
      .... 
     } 
    } 
} 

मैं निर्भरता इंजेक्शन के लिए Ninject का उपयोग कर रहा हूँ और मैं काफी यकीन है कि प्रभाव किस तरह का कथन का उपयोग अद्यतन कोड में होगा के बाद से पहले से ही Ninject PopClient का एक उदाहरण बनाया नहीं कर रहा हूँ और यह इंजेक्शन निर्माता में।

क्या उपयोग कथन पॉप 3 ऑब्जेक्ट का निपटान करेगा और पॉप क्लाइंट ऑब्जेक्ट को अकेले छोड़ देगा, इसलिए निनजेक्ट इसे संभाल सकता है या क्या उपयोग कथन निनजेक्ट में हस्तक्षेप करेगा?

इस मामले में उचित दृष्टिकोण क्या है? कोई अंतर्दृष्टि बहुत उपयोगी होगी।

+0

यदि आप पॉप क्लाइंट का निपटान करते हैं, तो MyProvider ऑब्जेक्ट का क्या होता है? इसे भी निपटान नहीं किया जाना चाहिए? क्योंकि कक्षा में एकमात्र डिस्पोजेड रीडोनली सदस्य छोड़ दिया गया है। यदि ऐसा है, तो मुझे लगता है कि MyProvider वर्ग के लिए एक निपटान विधि डालना बेहतर है। –

उत्तर

14

pop3 चर एक IPopClient वस्तु popClient है, इसलिए जब using बयान खत्म हो गया है, वस्तु दोनों स्थानीय और उदाहरण चर से जाना जाता निपटान किया जाएगा() घ के लिए एक ही संदर्भ दिया जाएगा, शायद रखकर आगे के उपयोग के लिए एक असंगत राज्य में। ,

public class MyProvider 
{ 
    private readonly Func<IPopClient> createPopClient; 

    public MyProvider(Func<IPopClient> popClientFactory) 
    { 
     this.createPopClient = popClientFactory; 
    } 

    public void Fetch() 
    { 
     using (var pop3 = createPopClient()) 
     { 
      .... 
     } 
    } 
} 

अब जब आप Fetch() कहते हैं, यह कारखाना निष्पादित करेंगे:

आप IPopClient के कई उदाहरण उपयोग करने के लिए, प्रति Fetch() कॉल एक चाहते हैं, क्या आपको क्या करना चाहिए एक "कारखाने विधि" इंजेक्षन है विधि जो IPopClient पर एक नया संदर्भ लौटाएगी, जिसका उपयोग किया जा सकता है और फिर उस विधि के किसी भी अन्य कॉल को प्रभावित किए बिना निपटान किया जा सकता है।

ऑटोफ़ैक किसी भी अतिरिक्त सेटअप के बिना पंजीकृत प्रकारों के लिए कारखाने के तरीकों को इंजेक्शन देने का समर्थन करता है (इसलिए यह नाम है, मुझे लगता है); मेरा मानना ​​है कि एक निंजा कंटेनर को कॉन्फ़िगर करते समय आपको किसी दिए गए रिटर्न प्रकार के लिए फैक्ट्री विधि के रूप में "गेटटर" को स्पष्ट रूप से पंजीकृत करना होगा (जो लैम्ब्डा ()=>new PopClient() के रूप में सरल हो सकता है या यह कंटेनर के रिज़ॉल्यूशन विधि पर कॉल का उपयोग कर सकता है)।

+1

बेहतर है। इरादा अधिक स्पष्ट है। फ़ैक्टरी पैटर्न – jgauffin

+0

के लिए कोई भी तरीका +1 जब तक आपके पास AppDomain.BaseDirectory में 'Ninject.Extensions.Factory.dll' है, Func स्वत: जेनरेट किया गया है - देखें [' Ninject.Extensions.Factory' विकी] (https: // github.com/ninject/ninject.extensions.factory/wiki/Func) (यानी कुछ भी पंजीकरण करने की आवश्यकता नहीं है) –

+0

मैं ऊपर @jgauffin द्वारा बनाई गई टिप्पणी को दूसरी बार दूंगा। एक कारखाना इंटरफेस थोड़ा और काम है, लेकिन यह लंबे समय तक भुगतान करेगा। इरादा स्पष्ट होगा, और मजाक करना भी आसान है। – Pflugs

1

जब आपके बाइंडिंग की स्थापना, गुंजाइश की घोषणा:

https://github.com/ninject/ninject/wiki/Object-Scopes

Ninject वस्तुओं यह आपके लिए बनाया पर निपटाने फोन करेगा, इसलिए किसी भी वस्तुओं आप को देने में यकीन है कि आप अपने निपटाने के तरीकों को लिख कर संभाल करने के लिए निंजा।

+0

समस्या यह है कि इसके साथ-साथ यह जिस तरह से स्थापित है, माइप्रोवाइडर को केवल आईपीओपी क्लाइंट ऑब्जेक्ट का उपयोग करने के लिए एक उदाहरण मिलता है; इसका मतलब है कि यदि कोड MyProvider के एक उदाहरण का उपयोग करके Fetch() को एकाधिक कॉल करता है, तो इससे कोई फर्क नहीं पड़ता कि आईपॉप क्लाइंट का पंजीकृत दायरा क्या है। – KeithS

+0

हां, वर्तमान कोड में कोई भी विधि विधि को कई बार नहीं कहा जाएगा (कोई DI) मैं हमेशा उपयोग कथन के कारण एक नया पॉप उदाहरण की गारंटी देता था। डीआई कोड में मेरा मानना ​​है कि क्षणिक दायरा केवल एक उदाहरण बनायेगा जिसका उपयोग कई कॉलों द्वारा किया जाएगा और पहली कॉल के बाद उपयोग का विवरण उस उदाहरण का निपटान करेगा। – Thomas

+0

@ थॉमस - यह बिल्कुल सही है - मेरा जवाब देखें।संक्षेप में, यदि आप उपयोग कथन को रखना चाहते हैं, तो आप एक उदाहरण को इंजेक्ट नहीं करना चाहते हैं, बल्कि इसके बजाय एक फैक्ट्री विधि जिसे आप चाहें उतने उदाहरण बनाने के लिए कॉल कर सकते हैं। एक कारखाना इंटरफ़ेस बनाने के लिए – KeithS

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