7

मैं एमवीसी 3, एंटिटी फ्रेमवर्क v4.3 कोड फर्स्ट, और सरल इंजेक्टर का उपयोग कर रहा हूं। मैं कई सरल वर्गों है कि इस तरह लग रहे है:नियंत्रक 0 इंजेक्शन निर्भरताओं की संख्या को कम करने के लिए कैसे करें

public class SomeThing 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 

मैं किसी अन्य संस्था है कि इस तरह दिखता है:

public class MainClass 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public virtual AThing AThingy { get; set; } 
    public virtual BThing BThingy { get; set; } 
    public virtual CThing CThingy { get; set; } 
    public virtual DThing DThingy { get; set; } 
    public virtual EThing EThingy { get; set; } 
} 

प्रत्येक thingy (वर्तमान में) तो तरह, अपने स्वयं के प्रबंधक वर्ग है:

public class SomeThingManager 
{ 
    private readonly IMyRepository<SomeThing> MyRepository; 

    public SomeThingManager(IMyRepository<SomeThing> myRepository) 
    { 
     MyRepository = myRepository; 
    } 
} 

मेरे MainController फलस्वरूप इस प्रकार है:

public class MainController 
{ 
    private readonly IMainManager MainManager; 
    private readonly IAThingManager AThingManager; 
    private readonly IBThingManager BThingManager; 
    private readonly ICThingManager CThingManager; 
    private readonly IDThingManager DThingManager; 
    private readonly IEThingManager EThingManager; 

    public MainController(IMainManager mainManager, IAThingManager aThingManager, IBThingManager bThingManager, ICThingManager cThingManager, IDThingManager dThingManager, IEThingManager eThingManager) 
    { 
     MainManager = mainManager; 
     AThingManager = aThingManager; 
     BThingManager = bThingManager; 
     CThingManager = cThingManager; 
     DThingManager = dThingManager; 
     EThingManager = eThingManager; 
    } 

    ...various ActionMethods... 
} 

हकीकत में, इस नियंत्रक में कई बार इंजेक्शन निर्भरताएं हैं। इसमें गंध है। गंध खराब होती है जब आप यह भी जानते हैं कि सभी या अधिकांश निर्भरताओं के साथ एक अन्य नियंत्रक है। मैं इसे दोबारा बनाना चाहता हूं।

मुझे पहले से ही डीआई के बारे में पता है कि संपत्ति इंजेक्शन और सेवा लोकेटर अच्छे विचार नहीं हैं।

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

मैंने परिवेश संदर्भ का उपयोग हास्य किया, लेकिन मैं सकारात्मक नहीं हूं कि यह जाने का सही तरीका है। मैंने एक फेकाडे इंजेक्शन लगाने के उपयोग को भी हास्य किया। मैं यह भी सोच रहा हूं कि मुझे इस बिंदु पर कमांड आर्किटेक्चर लागू करना चाहिए या नहीं। (उपर्युक्त सभी को कहीं और गंध को स्थानांतरित नहीं करें?)

आखिरकार, और शायद ऊपर दिए गए तीनों दृष्टिकोणों से स्वतंत्र, क्या मुझे इसके बजाय एक ही कहना चाहिए, लुकअपमेनर को गेटैटिंग्स जैसे स्पष्ट तरीकों से() , GetAThing (आईडी), GetBThings(), GetBThing (आईडी), और इतने पर? (लेकिन तब लुकअपमेनर को इसमें कई इंजेक्शन, या एक नए प्रकार के भंडार की आवश्यकता होगी।)

मेरी संगीत एक तरफ है, मेरा सवाल दोहराया जाना है: पागल संख्या को कम करने के लिए इस कोड को दोबारा करने का एक अच्छा तरीका क्या है इंजेक्शन निर्भरता?

+0

संभावित डुप्लिकेट [.NET में कन्स्ट्रक्टर ओवर-इंजेक्शन से कैसे निपटें] (http://stackoverflow.com/questions/4603555/how-to-deal-with-constructor-over-injection-in-net) – Steven

उत्तर

3

command architecture का उपयोग करना एक अच्छा विचार है, क्योंकि यह सभी व्यावसायिक तर्क नियंत्रक से बाहर चला जाता है, और आपको कोड में बदलाव किए बिना cross-cutting concerns जोड़ने की अनुमति देता है। हालांकि, यह constructor over-injection की आपकी समस्या को ठीक नहीं करेगा। मानक समाधान संबंधित निर्भरताओं को aggregate service में स्थानांतरित करना है। हालांकि, मैं मार्क से सहमत हूं कि आपको unit of work pattern पर एक नज़र डालना चाहिए।

+0

संदर्भों के लिए धन्यवाद। मुझे यह दृष्टिकोण पसंद है।मैं अपनी तत्काल जरूरतों के लिए एक समग्र सेवा के प्रति प्रतिक्रिया दूंगा और फिर कमांड आर्किटेक्चर और काम की इकाई पर गहराई से विचार करूंगा। –

+0

@Steven आप एक उदाहरण प्रदान कर सकते हैं कि यह SimpleInjector के साथ कैसे काम कर सकता है। मैं आपके उदाहरण का पालन कर रहा हूं http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=95 और यह एक उपयोगी दृष्टिकोण रहा है। मैं एक मुखौटा या कुल सेवा कैसे लागू कर सकता हूं। –

+0

@ डेविड क्लार्क: मुझे यकीन नहीं है कि क्या दिखाना है। यूनिट ऑफ वर्क पैटर्न पर नज़र डालें; यह आमतौर पर एक वर्ग है जो भंडार लपेट लेगा। काम की इकाई में कन्स्ट्रक्टर ओवर-इंजेक्शन को रोकने के लिए, आप ऐसे कारखाने को इंजेक्ट कर सकते हैं जो रिपोजिटरी को हल करने के बारे में जानता है। – Steven

4

क्या आपने कार्य डिजाइन पैटर्न की एक इकाई का उपयोग करने पर विचार किया है? काम की एक इकाई क्या है a great MSDN पोस्ट है। उस लेख से एक अंश:

एक तरह से, आप सभी लेन-देन से निपटने कोड डंप करने के लिए एक जगह के रूप में कार्य की इकाई के बारे में सोच सकते हैं। कार्य की इकाइयों की जिम्मेदारियां हैं:

  • लेनदेन प्रबंधित करें।
  • डेटाबेस आवेषण, हटाए गए और अद्यतनों को ऑर्डर करें।
  • डुप्लिकेट अपडेट रोकें। कार्य इकाई के एक इकाई के एक ही उपयोग के अंदर, कोड के विभिन्न हिस्सों में एक ही चालान
    ऑब्जेक्ट को बदल दिया जा सकता है, लेकिन वर्क क्लास का यूनिट केवल
    डेटाबेस में एकल अद्यतन आदेश जारी करेगा।

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

इसके बारे में कई ब्लॉग पोस्ट हैं, लेकिन मुझे सबसे अच्छा यह पता चला है कि इसे कैसे कार्यान्वित किया जाए here है। कुछ अन्य हैं जिन्हें इस साइट here, और here से संदर्भित किया गया है।

अन्त में, और शायद तीन से ऊपर तरीकों में से स्वतंत्र, मैं बजाय GetAThings तरह स्पष्ट तरीकों(), GetAThing (आईडी), GetBThings(), GetBThing (आईडी के साथ एक एकल, कहते हैं, LookupManager होना चाहिए), और इतने पर? (लेकिन तब कि LookupManager कई खजाने यह, या भंडार के एक नए प्रकार में इंजेक्शन की आवश्यकता होगी।)

काम की इकाई इन सभी संभाल करने में सक्षम होगा, खासकर यदि आप एक को लागू करने में सक्षम हो आपके अधिकांश डेटाबेस हैंडलिंग आवश्यकताओं के लिए सामान्य भंडार। आपका टैग उल्लेख करता है कि आप एंटिटी फ्रेमवर्क 4.3 का उपयोग कर रहे हैं?

आशा है कि इससे मदद मिलती है!

+0

[यहां] (http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=84) (अभी तक) कार्य पैटर्न की इकाई का एक और भिन्नता है। – Steven

+0

क्या मैं सिर्फ एक जंगल यूनिटऑफ वर्क क्लास बनाता हूं जो मेरे सभी नियंत्रक उपयोग करते हैं? मेरे पास पहले से ही जेनेरिक रिपोजिटरी है। वह वर्ग हर भंडार का संदर्भ देगा? –

+0

हाँ यह वही है जो यह करेगा। यह एकल इकाई वस्तुओं के समेकन को भी प्रबंधित करेगी जब उन्हें सभी अलग-अलग रिपोज़ से खींचा जा रहा है, साथ ही यह सुनिश्चित करता है कि आपके बीच केवल 1 साझा संदर्भ हो। –

0

मुझे लगता है कि आपका मुख्य मुद्दा अमूर्तता की कई परतें हैं। आप एंटिटी फ्रेमवर्क का उपयोग कर रहे हैं, इसलिए आपके पास पहले से ही डेटा के चारों ओर अमूर्तता की एक परत है, एक रिपोजिटरी के माध्यम से दो और परतें (एक प्रति इकाई) जोड़ना और एक प्रबंधक इंटरफ़ेस ने आपके नियंत्रक पर निर्भर करता है कि बड़ी संख्या में इंटरफेस पर निर्भर करता है। यह YAGNI के अलावा, बहुत सारे मूल्य को जोड़ता नहीं है।

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

फिर, अपने नियंत्रक प्रबंधक परतों से पूछे जाने वाले प्रश्नों के प्रकार देखें। जहां ये बहुत सरल हैं, मुझे आपके नियंत्रक में सीधे आपके 'परिवेश संदर्भ' से पूछताछ करने में कोई समस्या नहीं दिखती है - यही वह है जो मैं करता हूं। जहां वे अधिक जटिल हैं, इसे एक नए इंटरफेस में दोबारा दोहराएं, चीजों को तर्कसंगत रूप से समूहीकृत करें (आवश्यक रूप से एक प्रति इकाई नहीं) और इसके लिए अपने आईओसी का उपयोग करें।