2010-02-09 19 views
61

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

यहाँ कुछ स्थिति को दर्शाता हुआ कोड है:

interface IService 
{ 
    void Func(); 
} 

class StandardService : IService 
{ 
    public void Func() 
    { 
     Console.WriteLine("Standard"); 
    } 
} 

class AlternativeService : IService 
{ 
    public void Func() 
    { 
     Console.WriteLine("Alternative"); 
    } 
} 


class MyClass 
{ 
    public MyClass(IService service, int i) 
    { 
     this.service = service; 
    } 

    public void Func() 
    { 
     service.Func(); 
    } 

    IService service = null; 
} 
class Program 
{ 
    static void Main(string[] args) 
    { 
     IKernel kernel = new StandardKernel(new InlineModule(
      x => x.Bind<IService>().To<AlternativeService>(), 
      x => x.Bind<MyClass>().ToSelf())); 

     IService service = kernel.Get<IService>(); 

     MyClass m = kernel.Get<MyClass>(); 
     m.Func(); 
    } 
} 

उत्तर

84

With.ConstructorArgument इस उद्देश्य के लिए 1.0 में ही अस्तित्व में। 2.0 में, वाक्य रचना थोड़ा बदल गया है: - With.Parameters.ConstructorArgument with ninject 2.0

अधिक जानकारी और कैसे संदर्भ का उपयोग करने के उदाहरण के लिए Inject value into injected dependency, प्रदाताओं और तर्कों अधिक सही ढंग से इस के आसपास की तरह सामान पारित करने के लिए देखें।

संपादित करें: स्टीवन नाटक करने के लिए मेरी टिप्पणी अप्रासंगिक है चुना है के रूप में, मैं सबसे अच्छा स्पष्ट करना चाहते हैं कि मैं क्या कुछ उदाहरण के साथ कह रहा हूँ (2.0 के लिए):

MyClass m = kernel.Get<MyClass>(new ConstructorArgument("i", 2)); 

जो मेरी आँखों के लिए बहुत स्पष्ट है और बताता है कि क्या हो रहा है।

आप एक स्थान है जहाँ आप एक और अधिक वैश्विक जिस तरह से आप एक प्रदाता रजिस्टर कर सकते हैं में पैरामीटर निर्धारित और इस तरह यह कर सकते हैं में रहते हैं:

class MyClassProvider : SimpleProvider<MyClass> 
{ 
    protected override MyClass CreateInstance(IContext context) 
    { 
     return new MyClass(context.Kernel.Get<IService>(), CalculateINow()); 
    } 
} 

और इस तरह इसे पंजीकृत:

x => x.Bind<MyClass>().ToProvider(new MyClassProvider()) 

एनबी CalculateINow() बिट वह जगह है जहां आप अपने तर्क को पहले जवाब में डाल देंगे।

या इसे और अधिक इस तरह जटिल बना:

class MyClassProviderCustom : SimpleProvider<MyClass> 
{ 
    readonly Func<int> _calculateINow; 
    public MyClassProviderCustom(Func<int> calculateINow) 
    { 
     _calculateINow = calculateINow; 
    } 

    protected override MyClass CreateInstance(IContext context) 
    { 
     return new MyClass(context.Kernel.Get<IService>(), _calculateINow()); 
    } 
} 

जो तुम तो जैसे पंजीकृत चाहते हैं:

x => x.Bind<MyClass>().ToProvider(new MyClassProviderCustom(() => new Random().Next(9))) 

अद्यतन: नए तंत्र है जिसके ऊपर से भी कम समय बॉयलरप्लेट के साथ ज्यादा बेहतर पैटर्न का प्रदर्शन करते हैं Ninject.Extensions.Factory एक्सटेंशन में अवशोषित, देखें: https://github.com/ninject/ninject.extensions.factory/wiki

जैसा कि पहले बताया गया था, if you need to pass a different parameter each time and you have multiple levels in the dependency graph, you might need to do something like this।/गिरी (नमूने में TransientBehavior) जो तथ्य प्रस्तुत करना हो सकता है के लिए विकल्प में चूक

एक अंतिम विचार है कि क्योंकि आप एक Using<Behavior> निर्दिष्ट नहीं किया है, यह निर्दिष्ट के रूप में डिफ़ॉल्ट के लिए डिफ़ॉल्ट जा रहा है कि कारखाने i की गणना करता है फ्लाई मूट पर [उदाहरण के लिए, यदि यह ऑब्जेक्ट कैश किया जा रहा था]

अब, उन टिप्पणियों में कुछ अन्य बिंदुओं को स्पष्ट करने के लिए जो फ्यूड और चमकदार हैं। कुछ महत्वपूर्ण बातें डि उपयोग के बारे में विचार करने के लिए, यह Ninject है या जो कुछ भी करने के लिए है:

  1. संभव निर्माता इंजेक्शन के द्वारा किया जाता है ताकि आप न कंटेनर विशिष्ट विशेषताओं और चालें उपयोग करने की आवश्यकता के रूप में के रूप में ज्यादा है।Your IoC Container is Showing नामक एक अच्छी ब्लॉग पोस्ट है।

  2. कंटेनर पर जाने वाले कोड को कम करने और सामान मांगने के लिए - अन्यथा आपका कोड ए के साथ जोड़ा जाता है) विशिष्ट कंटेनर (जो सीएसएल कम कर सकता है) बी) जिस तरीके से आपकी पूरी परियोजना निर्धारित की जाती है। उस पर अच्छी ब्लॉग पोस्ट हैं जो दिखाती हैं कि सीएसएल ऐसा नहीं कर रहा है जो आपको लगता है। इस सामान्य विषय को Service Location vs Dependency Injection के रूप में जाना जाता है। अद्यतन: एक विस्तृत और पूर्ण तर्क के लिए http://blog.ploeh.dk/2011/07/28/CompositionRoot.aspx देखें।

  3. स्टैटिक्स और एकमात्र

  4. यह मानकर न चलें केवल एक [वैश्विक] कंटेनर है और यह सिर्फ यह मांग करने के लिए जब भी आप यह एक अच्छा वैश्विक चर की तरह की जरूरत है ठीक है कि के उपयोग को कम करें। एकाधिक मॉड्यूल और Bind.ToProvider() का सही उपयोग आपको इसे प्रबंधित करने के लिए एक संरचना देता है। इस तरह प्रत्येक अलग सबसिस्टम अपने दम पर काम कर सकते हैं और आप अभ्यस्त निम्न स्तर के घटकों उच्च-स्तरीय घटकों से बंधा किया जा रहा है, आदि

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

अब , अगर केवल जोएल आ सकता है और वास्तव में मुझे सीधे सिंटैक्स और/या ऐसा करने का सही तरीका है, तो मुझे सीधे सेट कर सकता है!

अद्यतन: एक ओर जहां इस उत्तर upvotes यह हुई है की संख्या से स्पष्ट रूप से उपयोगी है, मैं निम्नलिखित सिफारिश करने के लिए करना चाहते हैं:

  • ऊपर लगता है के रूप में यह एक बिट दिनांकित है और ईमानदारी से एक को दर्शाता है बहुत सारी अपूर्ण सोच जो Dependency Injection in .net पढ़ने के बाद लगभग शर्मनाक महसूस करती है - इसे चलाएं और अभी खरीदें - यह सिर्फ डीआई के बारे में नहीं है, पहला आधा उस व्यक्ति के आस-पास की सभी वास्तुकला चिंताओं का पूरा उपचार है जिसने यहां लटकने में बहुत अधिक समय बिताया है निर्भरता इंजेक्शन टैग के आसपास।
  • जाओ Mark Seemann's top rated posts here on SO right now पढ़ें - आप, हर एक
+0

इस खोजने के लिए अच्छा से मूल्यवान तकनीक सीखने जाएगा के बाद से अब तक प्रलेखन के पीछे है .... – Elton

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