निर्भरता इंजेक्शन (DI) "अनुकूल" पुस्तकालय


230

मैं एक C # लाइब्रेरी का डिज़ाइन तैयार कर रहा हूं, जिसमें कई अलग-अलग उच्च स्तर के कार्य होंगे। बेशक, उन उच्च-स्तरीय कार्यों को यथासंभव सोलिड क्लास डिजाइन सिद्धांतों का उपयोग करके लागू किया जाएगा । जैसे, संभवतः उपभोक्ताओं के लिए एक नियमित आधार पर सीधे उपयोग करने के लिए कक्षाएं होंगी, और "सहायता कक्षाएं" जो उन अधिक सामान्य "अंत उपयोगकर्ता" वर्गों की निर्भरता हैं।

सवाल यह है कि पुस्तकालय को डिजाइन करने का सबसे अच्छा तरीका क्या है:

  • DI अज्ञेयवादी - हालांकि आम DI पुस्तकालयों में से एक या दो के लिए बुनियादी "समर्थन" जोड़ना (स्ट्रक्चरुरपेज़, निनजेक्ट, आदि) उचित लगता है, मैं चाहता हूं कि उपभोक्ता किसी भी डीआई ढांचे के साथ पुस्तकालय का उपयोग करने में सक्षम हों।
  • गैर-डीआई प्रयोग करने योग्य - यदि लाइब्रेरी का कोई उपभोक्ता डीआई का उपयोग नहीं कर रहा है, तो लाइब्रेरी को अभी भी जितना संभव हो उतना उपयोग करना आसान होना चाहिए, एक उपयोगकर्ता को इन सभी "महत्वहीन" निर्भरताओं को बनाने के लिए काम करने की मात्रा को कम करना होगा। "वास्तविक" कक्षाएं वे उपयोग करना चाहते हैं।

मेरी वर्तमान सोच आम DI पुस्तकालयों के लिए कुछ "DI पंजीकरण मॉड्यूल" प्रदान करने की है (जैसे कि एक स्ट्रक्चररूप रजिस्ट्री, एक निन्यूज मॉड्यूल), और एक सेट या फैक्टरी कक्षाएं जो गैर-डीआई हैं और उन कुछ कारखानों को युग्मन प्रदान करती हैं।

विचार?


टूटे हुए लिंक लेख (SOLID) का नया संदर्भ: butunclebob.com/ArticleS.Unclebus.PrinciplesOfOod
M.Hassan

जवाबों:


360

यह वास्तव में एक बार करने के लिए सरल है जब आप समझते हैं कि DI पैटर्न और सिद्धांतों के बारे में है , न कि प्रौद्योगिकी।

एपीआई को डीआई कंटेनर-अज्ञेय तरीके से डिजाइन करने के लिए, इन सामान्य सिद्धांतों का पालन करें:

एक अंतरफलक के लिए कार्यक्रम, एक कार्यान्वयन नहीं

यह सिद्धांत वास्तव में डिजाइन पैटर्न से एक उद्धरण (स्मृति से हालांकि) है , लेकिन यह हमेशा आपका वास्तविक लक्ष्य होना चाहिए । DI केवल उस अंत को प्राप्त करने का एक साधन है

हॉलीवुड सिद्धांत लागू करें

DI के संदर्भ में हॉलीवुड सिद्धांत कहता है: DI कंटेनर को कॉल न करें, यह आपको कॉल करेगा

अपने कोड के भीतर से कंटेनर को कॉल करके सीधे निर्भरता के लिए कभी न पूछें। कन्स्ट्रक्टर इंजेक्शन का उपयोग करके इसके बारे में पूछें ।

कंस्ट्रक्टर इंजेक्शन का उपयोग करें

जब आपको एक निर्भरता की आवश्यकता होती है, तो इसे कंस्ट्रक्टर के माध्यम से सांख्यिकीय रूप से पूछें :

public class Service : IService
{
    private readonly ISomeDependency dep;

    public Service(ISomeDependency dep)
    {
        if (dep == null)
        {
            throw new ArgumentNullException("dep");
        }

        this.dep = dep;
    }

    public ISomeDependency Dependency
    {
        get { return this.dep; }
    }
}

ध्यान दें कि सेवा वर्ग अपने आक्रमणकारियों की गारंटी कैसे देता है। एक बार एक उदाहरण तैयार हो जाने के बाद, गार्ड क्लॉज और के संयोजन के कारण निर्भरता उपलब्ध होने की गारंटी हैreadonly कीवर्ड ।

यदि आपको एक अल्पकालिक वस्तु की आवश्यकता है तो एब्सट्रैक्ट फ़ैक्टरी का उपयोग करें

कंस्ट्रक्टर इंजेक्शन के साथ निर्भरताएं लंबे समय तक जीवित रहती हैं, लेकिन कभी-कभी आपको एक अल्पकालिक वस्तु की आवश्यकता होती है, या केवल रन-टाइम में ज्ञात मूल्य के आधार पर निर्भरता का निर्माण करने के लिए।

अधिक जानकारी के लिए इसे देखें ।

केवल अंतिम जिम्मेदार क्षण में लिखें

बहुत अंत तक वस्तुओं को सड़ने से बचाए रखें। आम तौर पर, आप आवेदन के प्रवेश बिंदु में सब कुछ इंतजार और तार कर सकते हैं। इसे कंपोजिशन रूट कहा जाता है

यहाँ अधिक जानकारी:

एक मुखौटा का उपयोग कर सरल करें

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

उच्च स्तर की खोज के साथ एक लचीला मुखौटा प्रदान करने के लिए, आप धाराप्रवाह बिल्डर्स प्रदान करने पर विचार कर सकते हैं। कुछ इस तरह:

public class MyFacade
{
    private IMyDependency dep;

    public MyFacade()
    {
        this.dep = new DefaultDependency();
    }

    public MyFacade WithDependency(IMyDependency dependency)
    {
        this.dep = dependency;
        return this;
    }

    public Foo CreateFoo()
    {
        return new Foo(this.dep);
    }
}

यह एक उपयोगकर्ता को लिखकर एक डिफ़ॉल्ट फू बनाने की अनुमति देगा

var foo = new MyFacade().CreateFoo();

हालांकि, यह बहुत खोज योग्य होगा कि कस्टम निर्भरता की आपूर्ति करना संभव है, और आप लिख सकते हैं

var foo = new MyFacade().WithDependency(new CustomDependency()).CreateFoo();

यदि आप कल्पना करते हैं कि MyFacade वर्ग अलग-अलग निर्भरता का एक बहुत कुछ करता है, तो मुझे आशा है कि यह स्पष्ट है कि यह कैसे विलक्षणता को खोज योग्य बनाते हुए उचित चूक प्रदान करेगा।


एफडब्ल्यूआईडब्ल्यू, इस उत्तर को लिखने के लंबे समय बाद, मैंने यहां की अवधारणाओं पर विस्तार किया और डीआई-फ्रेंडली लाइब्रेरी के बारे में लंबा ब्लॉग पोस्ट लिखा , और डीआई-फ्रेंडली फ्रेमवर्क के बारे में एक साथी पोस्ट ।


21
जबकि यह कागज पर बहुत अच्छा लगता है, मेरे अनुभव में एक बार जब आपके पास बहुत सारे आंतरिक घटक जटिल तरीकों से बातचीत करते हैं, तो आप रखरखाव के लिए बहुत सारे कारखानों के साथ समाप्त होते हैं, जिससे रखरखाव कठिन हो जाता है। इसके अलावा, कारखानों को अपने बनाए गए घटकों की जीवन शैली का प्रबंधन करना होगा, एक बार जब आप एक वास्तविक कंटेनर में पुस्तकालय स्थापित करते हैं तो यह कंटेनर के अपने जीवन शैली प्रबंधन के साथ संघर्ष करेगा। वास्तविक कंटेनरों के रास्ते में फैक्टरियाँ और फ़ेडेड्स मिलते हैं।
मौरिसियो शेफ़र

4
मुझे अभी तक एक परियोजना ढूंढनी है जो यह सब करती है ।
मौरिसियो शेफ़र

31
खैर, यह है कि हम Safewhere में सॉफ्टवेयर कैसे विकसित करते हैं, इसलिए हम आपके अनुभव को साझा नहीं करते ...
मार्क सेमन

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

8
यह एकमात्र सबसे अच्छा उत्तर हो सकता है जिसे मैंने SO पर देखा है।
निक हॉजेस

40

"निर्भरता इंजेक्शन" शब्द का विशेष रूप से आईओसी कंटेनर के साथ कुछ भी करने के लिए कुछ भी नहीं है, भले ही आप उन्हें एक साथ उल्लेख करते हुए देखें। इसका सीधा सा मतलब है कि इस तरह अपना कोड लिखने के बजाय:

public class Service
{
    public Service()
    {
    }

    public void DoSomething()
    {
        SqlConnection connection = new SqlConnection("some connection string");
        WindowsIdentity identity = WindowsIdentity.GetCurrent();
        // Do something with connection and identity variables
    }
}

आप इसे इस तरह लिखते हैं:

public class Service
{
    public Service(IDbConnection connection, IIdentity identity)
    {
        this.Connection = connection;
        this.Identity = identity;
    }

    public void DoSomething()
    {
        // Do something with Connection and Identity properties
    }

    protected IDbConnection Connection { get; private set; }
    protected IIdentity Identity { get; private set; }
}

जब आप अपना कोड लिखते हैं, तो आप दो काम करते हैं:

  1. जब भी आपको लगता है कि कार्यान्वयन को बदलने की आवश्यकता हो सकती है वर्गों के बजाय इंटरफेस पर भरोसा करें;

  2. एक वर्ग के अंदर इन इंटरफेस के उदाहरण बनाने के बजाय, उन्हें निर्माता के तर्क के रूप में पारित करें (वैकल्पिक रूप से, वे सार्वजनिक गुणों के लिए हो सकते हैं, पूर्व निर्माणकर्ता इंजेक्शन है , बाद वाला संपत्ति इंजेक्शन है )।

इसमें से कोई भी किसी भी डीआई लाइब्रेरी के अस्तित्व को निर्धारित नहीं करता है, और यह वास्तव में किसी के बिना लिखने के लिए कोड को और अधिक कठिन नहीं बनाता है।

यदि आप इसका एक उदाहरण देख रहे हैं, तो .NET फ्रेमवर्क की तुलना में आगे नहीं देखें:

  • List<T>लागू होता है IList<T>। यदि आप अपनी कक्षा को उपयोग करने IList<T>(या IEnumerable<T>) के लिए डिज़ाइन करते हैं , तो आप आलसी-लोडिंग जैसी अवधारणाओं का लाभ उठा सकते हैं, जैसे कि लाइनक टू एसक्यूएल, लाइनक टू एंटिटीज़, और एनएचबर्नेट सभी पर्दे के पीछे करते हैं, आमतौर पर संपत्ति इंजेक्शन के माध्यम से। कुछ फ्रेमवर्क क्लासेस वास्तव IList<T>में एक कंस्ट्रक्टर तर्क के रूप में स्वीकार करते हैं , जैसे कि BindingList<T>, जो कई डेटा बाइंडिंग सुविधाओं के लिए उपयोग किया जाता है।

  • Linq to SQL और EF पूरी तरह से IDbConnectionऔर संबंधित इंटरफेस के आसपास बनाए गए हैं , जिन्हें सार्वजनिक निर्माणकर्ताओं के माध्यम से पारित किया जा सकता है। हालांकि, आपको उनका उपयोग करने की आवश्यकता नहीं है; डिफ़ॉल्ट कंस्ट्रक्टर कहीं कनेक्शन फ़ाइल में बैठे कनेक्शन स्ट्रिंग के साथ ठीक काम करते हैं।

  • यदि आप कभी भी WinForms घटकों पर काम करते हैं, तो आप "सेवाओं" के साथ सौदा करते हैं, जैसे INameCreationServiceया IExtenderProviderService। तुम भी वास्तव में नहीं जानते कि ठोस वर्ग क्या हैं । .NET वास्तव में अपना स्वयं का IoC कंटेनर है, IContainerजिसका उपयोग इसके लिए किया जाता है, और Componentकक्षा में एक GetServiceविधि है जो वास्तविक सेवा लोकेटर है। बेशक, कुछ भी आपको IContainerया उस विशेष लोकेटर के बिना इन सभी इंटरफेस का उपयोग करने से रोकता है । स्वयं सेवाएं केवल कंटेनर के साथ शिथिल-युग्मित हैं।

  • डब्ल्यूसीएफ में अनुबंध पूरी तरह से इंटरफेस के आसपास निर्मित होते हैं। वास्तविक ठोस सेवा वर्ग को आमतौर पर कॉन्फ़िगरेशन फ़ाइल में नाम से संदर्भित किया जाता है, जो अनिवार्य रूप से DI है। बहुत से लोगों को इसका एहसास नहीं होता है, लेकिन इस कॉन्फ़िगरेशन सिस्टम को किसी अन्य IoC कंटेनर के साथ स्वैप करना पूरी तरह से संभव है। शायद अधिक दिलचस्प है, सेवा व्यवहार सभी उदाहरण हैं, IServiceBehaviorजिन्हें बाद में जोड़ा जा सकता है। फिर, आप इसे आसानी से एक IoC कंटेनर में तार कर सकते हैं और इसे संबंधित व्यवहार चुन सकते हैं, लेकिन यह सुविधा एक के बिना पूरी तरह से उपयोग करने योग्य है।

इत्यादि इत्यादि। आपको .NET में सभी जगह DI मिल जाएगा, यह सिर्फ इतना है कि आम तौर पर यह इतना निर्बाध रूप से किया जाता है कि आप इसे DI के रूप में भी नहीं सोचते हैं।

यदि आप अपने DI- सक्षम पुस्तकालय को अधिकतम प्रयोज्यता के लिए डिज़ाइन करना चाहते हैं तो सबसे अच्छा सुझाव है कि आप हल्के कंटेनर का उपयोग करके अपने स्वयं के डिफ़ॉल्ट IoC कार्यान्वयन की आपूर्ति करें। IContainerइसके लिए एक बढ़िया विकल्प है क्योंकि यह .NET फ्रेमवर्क का एक हिस्सा है।


2
एक कंटेनर के लिए वास्तविक अमूर्त IServiceProvider है, न कि IContainer।
मौरिसियो शेफ़र

2
@ मौरिसियो: आप निश्चित रूप से सही हैं, लेकिन किसी ऐसे व्यक्ति को समझाने की कोशिश करें जिसने कभी एलडब्ल्यूसी प्रणाली का इस्तेमाल नहीं किया IContainerहै, वास्तव में एक पैराग्राफ में कंटेनर क्यों नहीं है। ;)
Aaronaught

हारून, सिर्फ इस बात के लिए उत्सुक हैं कि आप निजी सेट का उपयोग क्यों करते हैं; खेतों को केवल पठनीय रूप से निर्दिष्ट करने के बजाय?
jr3

@ जयवीर: आपका मतलब है कि वे private readonlyफील्ड क्यों नहीं हैं? यह बहुत अच्छा है यदि वे केवल घोषित वर्ग द्वारा उपयोग किए जाते हैं, लेकिन ओपी ने निर्दिष्ट किया कि यह फ्रेमवर्क / लाइब्रेरी-स्तरीय कोड था, जिसका अर्थ है उपवर्ग। ऐसे मामलों में आप आमतौर पर उपवर्गों के सामने महत्वपूर्ण निर्भरता चाहते हैं। मैं एक private readonlyक्षेत्र और एक संपत्ति लिख सकता था जिसमें स्पष्ट गेटर्स / सेटर थे, लेकिन ... एक उदाहरण में व्यर्थ जगह, और व्यवहार में बनाए रखने के लिए अधिक कोड, कोई वास्तविक लाभ के लिए नहीं।
आरोन

स्पष्ट करने के लिए आपको धन्यवाद! मैंने माना कि बच्चे द्वारा आसानी से खेतों को पहुँचा जा सकता है।
jr3

5

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

मूल उत्तर इस प्रकार है:


मुझे उसी निर्णय का सामना करना पड़ा जबकि सोल्रनेट विकसित कर रहा था । मैंने डि-फ्रेंडली और कंटेनर-अज्ञेयवादी होने के लक्ष्य के साथ शुरुआत की, लेकिन जैसा कि मैंने अधिक से अधिक आंतरिक घटकों को जोड़ा, आंतरिक कारखाने जल्दी से असहनीय हो गए और परिणामस्वरूप लाइब्रेरी अनम्य थी।

मैंने विंडसर सुविधा और एक निन्यूज मॉड्यूल प्रदान करते हुए अपने बहुत ही सरल एम्बेडेड आईओसी कंटेनर को लिखना समाप्त कर दिया । अन्य कंटेनरों के साथ पुस्तकालय को एकीकृत करना ठीक से घटकों को तार करने की बात है, इसलिए मैं इसे आसानी से ऑटोफैक, यूनिटी, स्ट्रक्चर्सपाइप, जो भी हो, के साथ एकीकृत कर सकता हूं।

इसका नकारात्मक पक्ष यह है कि मैंने सिर्फ newसेवा करने की क्षमता खो दी । मैंने CommonServiceLocator पर भी निर्भरता ली जिसे मैं टाल सकता था (मैं भविष्य में इसे वापस कर सकता हूं) एम्बेडेड कंटेनर को लागू करने के लिए आसान बनाने के लिए।

इस ब्लॉग पोस्ट में अधिक जानकारी ।

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

मोनोरेल को लागू करता है उसका अपना कंटेनर के साथ-साथ अच्छे पुराने, जो औजार IServiceProvider । इस कंटेनर का उपयोग इस ढांचे के माध्यम से एक इंटरफ़ेस के माध्यम से किया जाता है जो कि प्रसिद्ध सेवाओं को उजागर करता है । कंक्रीट कंटेनर प्राप्त करने के लिए, इसमें एक अंतर्निहित सेवा प्रदाता लोकेटर हैविंडसर सुविधा विंडसर को यह सेवा प्रदाता लोकेटर बताते हैं, यह चयनित सेवा प्रदाता बन गया है।

नीचे पंक्ति: कोई सही समाधान नहीं है। किसी भी डिजाइन निर्णय के साथ, यह मुद्दा लचीलापन, स्थिरता और सुविधा के बीच संतुलन की मांग करता है।


12
जब मैं आपकी राय का सम्मान करता हूं, तो मुझे आपका अति-सामान्यीकृत लगता है "यहां अन्य सभी उत्तर पुराने हैं और" बेहद भोले होने से बचना चाहिए। अगर हमने कुछ भी सीखा है, तो यह निर्भरता इंजेक्शन भाषा की सीमाओं का जवाब है। हमारी वर्तमान भाषाओं को विकसित करने या छोड़ने के बिना, ऐसा लगता है कि हमें अपने आर्किटेक्चर को समतल करने और प्रतिरूपकता प्राप्त करने के लिए DI की आवश्यकता होगी । एक सामान्य अवधारणा के रूप में IoC इन लक्ष्यों का एक परिणाम है और निश्चित रूप से एक वांछनीय है। आईओसी कंटेनर आईओसी या डीआई के लिए बिल्कुल आवश्यक नहीं हैं, और उनकी उपयोगिता हमारे द्वारा बनाई गई मॉड्यूल रचनाओं पर निर्भर करती है।
tne

@ मेरे लिए आपका उल्लेख "अत्यंत भोला" होने के नाते एक गैर-स्वागत योग्य विज्ञापन-गृहिणी है। मैंने C #, VB.NET, Java में DI या IoC के बिना जटिल एप्लिकेशन लिखे हैं (जावा जो भाषाएं आपको "आवश्यकता होगी" IoC जाहिरा तौर पर आपके विवरण को देखते हुए), यह निश्चित रूप से भाषाओं की सीमाओं के बारे में नहीं है। यह वैचारिक सीमाओं के बारे में है। मैं आपको विज्ञापन-होमिनम हमलों और खराब तर्कों का सहारा लेने के बजाय कार्यात्मक प्रोग्रामिंग के बारे में जानने के लिए आमंत्रित करता हूं।
मौरिसियो शेफ़र

18
मैंने उल्लेख किया है कि मैंने आपके कथन को अनुभवहीन पाया ; यह आपके बारे में व्यक्तिगत रूप से कुछ नहीं कहता है और मेरी राय के बारे में है। कृपया बेतरतीब अजनबी का अपमान न करें। सभी प्रासंगिक कार्यात्मक प्रोग्रामिंग दृष्टिकोणों से अनभिज्ञ होने के कारण मैं सहायक नहीं हूं; आप यह नहीं जानते, और आप गलत होंगे। मुझे पता था कि आप वहाँ के जानकार थे (जल्दी से अपने ब्लॉग पर नज़र डालते हैं), यही कारण है कि मुझे यह कष्टप्रद लगता है कि एक जान-पहचान वाला आदमी "हमें आईओसी की जरूरत नहीं है" जैसी चीजें कहेगा। आईओसी कार्यात्मक प्रोग्रामिंग में हर जगह सचमुच होता है (..)
tne

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

1
आईओसी कंटेनर ग्लोबल म्यूटेबल डिक्शनरी हैं, तर्क के लिए एक उपकरण के रूप में पैरामीट्रिकिटी को दूर करते हैं, इसलिए इससे बचा जाना चाहिए। आईओसी (अवधारणा) के रूप में "हमें कॉल न करें हम आपको कॉल करेंगे" हर बार जब आप किसी फ़ंक्शन को मान के रूप में पास करते हैं तो तकनीकी रूप से लागू होता है। DI के बजाय, ADTs के साथ अपने डोमेन को मॉडल करें फिर दुभाषियों को लिखें (cf Free)।
मौरिसियो शेफ़र

1

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

फिर लाइब्रेरी के उपयोगकर्ताओं के लिए DI तर्क के ऊपर की परत को उजागर करें ताकि वे आपके इंटरफ़ेस के माध्यम से आपके द्वारा चुने गए ढांचे का उपयोग कर सकें। इस तरह वे अभी भी DI कार्यक्षमता का उपयोग कर सकते हैं जिसे आपने उजागर किया है और वे अपने स्वयं के प्रयोजनों के लिए किसी अन्य ढांचे का उपयोग करने के लिए स्वतंत्र हैं।

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.