7

अभी मेरे पास कुछ ऐसी सेवाएं हैं जो एक असेंबली में परिभाषित की गई हैं जो आईओसी कंटेनर (मेरे मामले में निंजा) पर निर्भर नहीं है। मुख्य परियोजना में मेरे पास कंटेनर में पंजीकृत डेटा एक्सेस के लिए एक आईरिपॉजिटरी है।सामान्य आईओसी अभ्यास - क्या सेवाओं के लिए एक-दूसरे पर निर्भर होना गलत है?

this.Bind<IRepository>().To<EntityFrameworkRepository<MyDatabaseEntities>>(); 

मैं भी IAuthenticationService और IErrorLogger सेवाओं पंजीकृत किया है, जिसका ठोस कार्यान्वयन मैं उनके तर्क के लिए भंडार का उपयोग करना चाहते। हालांकि, मुझे यकीन नहीं है कि इसे कैसे पूरा किया जाए। वर्तमान में, दोनों ठोस कार्यान्वयन पर अपने निर्माता एक IRepository पैरामीटर लेने के लिए और मैं इसे जब मैं उन्हें रजिस्टर में पारित:

this.Bind<IAuthenticationService>().To<MyAuthenticationService>(). 
       WithConstructorArgument("myRepository", ctx => ctx.Kernel.Get<IRepository()); 

यहाँ मैं सिर्फ IRepository उदाहरण पकड़ें और उसे निर्माता को पारित करने के लिए कंटेनर बताओ।

मुझे अपनी सेवा असेंबली को निंजा या यहां तक ​​कि सामान्य सेवा लोकेटर (सीएसएल) पर निर्भर करने का अधिकार नहीं था, लेकिन मुझे अपने वर्तमान तरीके के बारे में भी यकीन नहीं है। मैं राय और वैकल्पिक समाधान की तलाश में हूं।

यदि मेरी अन्य सेवाएं आईरिपोजिटरी का उपयोग नहीं करती हैं, तो मुझे इन सेवाओं के अंतर्निहित आईरिपोजिटरी प्रकार (जैसे नकली और वास्तविक डेटा दोनों के लिए प्रमाणीकरण सेवा) के लिए इन सेवाओं के नए ठोस कार्यान्वयन करना होगा। यह बहुत तर्क दोहराव होगा।

उत्तर

6

आपकी सेवा असेंबली केवल निंजा पर निर्भर नहीं होनी चाहिए, केवल उन इंटरफ़ेस पर जिन्हें आप अपने ठोस प्रकार पंजीकृत करते हैं। आईओसी कंटेनर केवल अपनी कक्षाओं में निर्भरताओं को इंजेक्ट करने के लिए कुल रूट होना चाहिए। असेंबली जिसमें दूसरी ओर कुल रूट/निनजेक कर्नेल शामिल है, उन सभी असेंबली पर निर्भर करेगा जिनमें ठोस प्रकार होते हैं (यह उन्हें कैसे हल कर पाएगा?)।

आईओसी के साथ सामान्य तौर पर आप Hollywood principle यहाँ लागू करना चाहिए - (निर्माता इंजेक्शन यदि संभव हो उपयोग करते हुए) आप अपने ठोस वस्तु उदाहरणों को निर्भरता देना चाहिए, न जाने वस्तु उदाहरणों उनकी निर्भरता के लिए पूछना।

उदाहरण आप WithConstructorArgument() के लिए उपयोग करते हैं, सब वास्तव में पर जरूरत नहीं किया जाना चाहिए निर्भरता संकल्प रिकर्सिवली काम करता है के बाद से: आप दोनों IRepository और IAuthenticationService कंटेनर के साथ पंजीकृत है, तो यह कैसे दोनों को हल करने को जानता है। क्योंकि IAuthenticationServiceAuthenticationService से जुड़ा हुआ है, इसलिए आपको कन्स्ट्रक्टर तर्क निर्दिष्ट करने की आवश्यकता नहीं है क्योंकि यह IRepository प्रकार है और स्वचालित रूप से हल हो जाएगा।

पुनरावृत्ति करने के लिए के रूप में - बेशक आप विभिन्न कार्यान्वयन संभालने विभिन्न भंडार प्रकार के लिए IRepository के लिए बनाना पड़ेगा आप इन संग्रहों के अलग व्यवहार चाहते हैं।

+0

महान जानकारी! आप सही हैं, मुझे बिल्कुल WithConstructorArgument निर्दिष्ट करने की आवश्यकता नहीं थी। वे स्वचालित रूप से इंजेक्शन दिए गए थे। एक और सवाल यह है कि यदि मैं 2 आईरिपोजिटरी कार्यान्वयन पंजीकृत करता हूं, प्रत्येक एक अलग नाम के साथ। तो मैं इंजेक्ट करने के लिए एक निर्दिष्ट करना चाहता हूँ। मुझे पता है कि निनजेक्ट के साथ नामांकित एट्रिब्यूट है, लेकिन मेरी सेवा असेंबली में निनजेक्ट निर्भरता जोड़ने से बचने के लिए मैं इसका उपयोग नहीं करना चाहूंगा। तो मैन्युअल रूप से निर्दिष्ट करना इस मामले में जाने का तरीका होगा? एफवाईआई, मेरी पुनरावृत्ति चिंता आईरिपोजिटरी के बारे में नहीं बल्कि अन्य सेवा वर्गों के बारे में थी। – Adam

+2

निनजेक्ट के लिए आप 'WhenInjectedInto ()' का उपयोग कर सकते हैं, जहां फू आपकी सेवा कक्षा है।आम तौर पर आप केवल अपने भंडार के एक ठोस कार्यान्वयन को पंजीकृत करेंगे - नकली डेटा और परीक्षण के लिए आपके मुख्य आवेदन के हिस्से के रूप में पंजीकृत नहीं होना चाहिए, केवल एक अलग परीक्षण कंटेनर – BrokenGlass

+0

परफेक्ट, फिर से धन्यवाद। – Adam