2012-09-05 20 views
15

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

[Inject] 
public HomeController(
    UserManager userManager, RoleManager roleManager, BlahblahManager blahblahManager) { 
    _userManager = userManager; 
    _roleManager = roleManager; 
    _blahblahManager = blahblahManager; 
} 

क्या होगा यदि मैं एक बार में इन कक्षाओं के सभी उदाहरणों के लिए नहीं करना चाहते?

जिस तरह से ये सभी वर्ग Lazy<T> द्वारा लिपटे हैं और कन्स्ट्रक्टर को पास किया गया है, वही नहीं है जो मुझे चाहिए। T उदाहरण अभी तक नहीं बनाए गए हैं, लेकिन Lazy<T> उदाहरण पहले से ही स्मृति में संग्रहीत हैं।

मेरा सहयोगी मुझे सभी तत्कालताओं पर नियंत्रण रखने के लिए फैक्टरी पैटर्न का उपयोग करने का सुझाव दे रहा है, लेकिन मुझे यकीन नहीं है कि आईओसी में ऐसी महान डिज़ाइन बग है।

क्या इस स्थिति के लिए कोई कामकाज है या आईओसी वास्तव में इसके डिजाइन में इतना बड़ा दोष है? शायद मुझे एक और आईओसी कंटेनर का उपयोग करना चाहिए?

कोई सुझाव?

+0

आपकी समस्या वास्तव में क्या है? आप इन उदाहरणों को क्यों नहीं चाहते हैं? –

+2

मैं नियंत्रक के काम के दौरान UserManager चाहता हूं, लेकिन RoleManager की आवश्यकता नहीं है और इसके विपरीत। यदि आप आलसी उदाहरणों के बारे में बात करते हैं, तो यह स्मृति में उन्हें रखने का एक बड़ा सौदा नहीं है, लेकिन क्या यह एकमात्र तरीका है? – xwrs

+1

यह 'UserManager' और' RoleManager' के लिए एक बड़ा सौदा क्यों है? आपके रचनाकारों को वैसे भी भारी काम नहीं करना चाहिए। –

उत्तर

36

मुझे लगता है कि आप premature optimization कर रहे हैं: ऐसा न करें।

आपकी सेवाओं के रचनाकारों को निजी क्षेत्रों में निर्भरता को संग्रहीत करने से nothing more करना चाहिए। उस स्थिति में ऐसी वस्तु का निर्माण वास्तव में हल्का वजन है। भूलें कि .NET में ऑब्जेक्ट सृजन वास्तव में तेज़ है। ज्यादातर मामलों में, एक प्रदर्शन परिप्रेक्ष्य से, इससे कोई फर्क नहीं पड़ता कि उन निर्भरताओं को इंजेक्शन दिया गया है या नहीं। खासकर जब वस्तुओं की मात्रा की तुलना में आपके शेष आवेदन (और आपके द्वारा उपयोग किए जाने वाले ढांचे) की तुलना में थका रहे हैं। असली लागत तब होती है जब आप वेब सेवाओं, डेटाबेस या फ़ाइल सिस्टम (या सामान्य रूप से I/O) का उपयोग शुरू करते हैं, क्योंकि वे बहुत अधिक देरी का कारण बनते हैं।

तो निर्माण वास्तव में महंगा है, आप सामान्य रूप से एक Virtual Proxy के पीछे निर्माण के बजाय हर उपभोक्ता में एक Lazy<T> इंजेक्शन लगाने की, छुपाना चाहिए, क्योंकि यह आम आवेदन कोड तथ्य निर्माण में देरी करने के लिए एक तंत्र है कि वहाँ से अनजान रहने की अनुमति देता (जब आप ऐसा करते हैं तो आपका एप्लिकेशन कोड और टेस्ट कोड दोनों जटिल हो रहे हैं)।

Dependency Injection in .NET, second edition के अध्याय 6 में आलसी और वर्चुअल प्रॉक्सी के बारे में अधिक विस्तृत चर्चा शामिल है।

हालांकि, एक Lazy<T> सिर्फ स्मृति के 20 बाइट (और उसके लिपटे Func<T> के लिए एक और 24 bytes, एक 32bit प्रक्रिया मानकर) की खपत है, और एक Lazy<T> उदाहरण के निर्माण के व्यावहारिक रूप से स्वतंत्र है। इसलिए इसके बारे में चिंता करने की कोई आवश्यकता नहीं है, सिवाय इसके कि जब आप वास्तव में तंग स्मृति बाधाओं वाले माहौल में हों।

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

ध्यान दें कि निनजेक्ट .NET के लिए धीमी डी पुस्तकालयों में से एक है। यदि यह आपको परेशान कर रहा है, switch to a faster container। कुछ कंटेनर में प्रदर्शन होता है जो हाथ से ऑब्जेक्ट ग्राफ़ को नए करने के करीब होता है। लेकिन हर तरह से, यह प्रोफ़ाइल करें, कई डेवलपर्स गलत कारणों से DI पुस्तकालयों को स्विच करते हैं।

ध्यान दें कि निर्भरता के रूप में Lazy<T> का उपयोग leaky abstraction (Dependency Inversion Principle का उल्लंघन) है। अधिक जानकारी के लिए कृपया this answer पढ़ें।

+0

धन्यवाद। आपने स्थिति की मेरी समझ को और स्पष्ट कर दिया। – xwrs

+0

मुझे नहीं लगता कि यह समयपूर्व अनुकूलन है, इस तर्क के साथ ऐसा लगता है कि आलसी के लिए कभी भी आवश्यकता नहीं है, एक वस्तु बनाना भारी नहीं है लेकिन आप नहीं जानते कि यह अपने कन्स्ट्रक्टर में कितनी वस्तुएं बना रहा है। और कुछ दूरस्थ संसाधन खोलना जो उपयोग नहीं किया जा सकता है। –

0

न्यू

स्टीवन कह रही है कि यह समय से पहले अनुकूलन की तरह दिखता है में सही है। इन वस्तुओं का निर्माण बहुत तेज़ है और आमतौर पर कभी बाधा नहीं होती है।

हालांकि आलसी का उपयोग निर्भरता व्यक्त करने के लिए आपको तुरंत आवश्यकता नहीं है निर्भरता इंजेक्शन ढांचे में एक आम पैटर्न है। Actofac एक ऐसा कंटेनर है जिसने various wrapping types के लिए समर्थन में बनाया है। मुझे यकीन है कि निनजेक के लिए भी एक विस्तार है, शायद इस पर एक नज़र डालें, Ninject Lazy

+1

तथ्य यह है कि डी कंटेनरों को आलसी के लिए समर्थन है, यह आपके आवेदन कोड को आलसी निर्भरता पर निर्भर करने का अधिकार नहीं देता है। कई डी कंटेनर उन सुविधाओं का समर्थन करते हैं जो सर्वोत्तम प्रथाओं को बढ़ावा नहीं देते हैं। एक निर्भरता इंजेक्शन परिप्रेक्ष्य से, आलसी एक लीकी अमूर्त है। आलसी लीक पर क्यों स्पष्टीकरण के लिए कृपया [यह] (https://stackoverflow.com/a/21724609/264697) पढ़ें। – Steven

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