2012-06-11 16 views
9

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


मैं एक समाधान कई वर्गों है कि सभी एक ही इंटरफ़ेस

एक साधारण उदाहरण के रूप को लागू किया है,

public class MyClassOne : IMyInterface { 
    public string GetString() { 
     .... 
    } 
    public int GetInt() { 
     .... 
    } 
} 

public class MyClassTwo : IMyInterface { 
    public string GetString() { 
     .... 
    } 
    public int GetInt() { 
     .... 
    } 
} 

अब Interface

public interface IMyInterface { 
    string GetString(); 
    int GetInt(); 
    ... 
} 

ठोस वर्ग है इन वर्गों को इंजेक्शन दिया जाएगा जहां उनके ऊपर परतों की आवश्यकता होती है जैसे:

public class HomeController { 

    private readonly IMyInterface myInterface; 

    public HomeController() {} 

    public HomeController(IMyInterface _myInterface) { 
     myInterface = _myInterface 
    } 
    ... 
} 

public class OtherController { 

    private readonly IMyInterface myInterface; 

    public OtherController() {} 

    public OtherController(IMyInterface _myInterface) { 
     myInterface = _myInterface 
    } 
    ... 
} 

दोनों नियंत्रक एक ही इंटरफ़ेस से इंजेक्शन प्राप्त कर रहे हैं।

यह मेरी आईओसी में उचित ठोस वर्ग के साथ इन इंटरफेस को हल करने, मैं कैसे अंतर कि HomeControllerMyClassOne का एक उदाहरण की जरूरत है और OtherControllerMyClassTwo का एक उदाहरण की जरूरत है की बात आती है?

आईओसी में एक ही इंटरफेस में दो अलग कंक्रीट कक्षाओं को कैसे बांधूं? मैं 2 अलग-अलग इंटरफेस नहीं बनाना चाहता क्योंकि यह DRY नियम को तोड़ता है और वैसे भी समझ में नहीं आता है।

कैसल विंडसर में मैं 2 लाइनों इस तरह होगा:

container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassOne>()); 
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassTwo>()); 

इसका कारण यह है कि मैं केवल कभी MyClassTwo की एक प्रति है क्योंकि यह इंटरफेस के लिए पंजीकृत पिछले एक है मिल जाएगा काम नहीं करेगा।

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


अद्यतन मार्क Polsen के जवाब


यहाँ मेरे वर्तमान आईओसी, जहां .Resolve बयान जाना होगा है के आधार पर? मैं 'डॉन विंडसर डॉक्स

public class Dependency : IDependency { 

    private readonly WindsorContainer container = new WindsorContainer(); 

    private IDependency() { 
    } 

    public IDependency AddWeb() { 
     ... 

     container.Register(Component.For<IListItemRepository>().ImplementedBy<ProgramTypeRepository>().Named("ProgramTypeList")); 
     container.Register(Component.For<IListItemRepository>().ImplementedBy<IndexTypeRepository>().Named("IndexTypeList")); 

     return this; 
    } 

    public static IDependency Start() { 
     return new IDependency(); 
    } 
} 
+0

आप यदि आवश्यक हो तो ठोस वर्ग के लिए सीधे बाध्य कर सकते हैं। (ठीक है, कम से कम निनजेक्ट के साथ आप कर सकते हैं लेकिन मैं कल्पना नहीं कर सकता कि आप इसे अन्य डुबकी के साथ नहीं कर सकते हैं।) – Buildstarted

+0

आप ऐसा नहीं करना चाहते हैं। आपकी कक्षाओं की निर्भरता संदिग्ध है। आप केवल कक्षाओं में से किसी एक को नहीं देख सकते हैं और बता सकते हैं कि इसे एक विशिष्ट कार्यान्वयन की आवश्यकता है। मैं अनुशंसा करता हूं कि आप एक कारखाने का उपयोग दोनों वर्गों में निर्भरता के रूप में करें। यहां और पढ़ें: http://www.codeproject.com/Articles/386164/Get-injected-into-the-world-of-inverted-dependenci – jgauffin

+0

@jgauffin विंडसर की 'नामांकित (...)' विधि का वादा यह है कि यह उस अस्पष्टता को हल कर सकता है, लेकिन वास्तविक उपयोग में, मुझे कुछ भी हल करने के लिए विंडसर नहीं मिल सकता है :-( –

उत्तर

5

आपको इसे नामांकित घटक पंजीकरण के साथ पूरा करने में सक्षम होना चाहिए।

container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassOne>().Named("One")); 
container.Register(Component.For<IMyInterface>().ImplementedBy<MyClassTwo>().Named("Two")); 

और फिर उनके साथ

kernel.Resolve<IMyInterface>("One"); 

या

kernel.Resolve<IMyInterface>("Two"); 

See: To specify a name for the component

+0

यह आशाजनक लग रहा है! –

+0

मैं कैसल विंडसर का उपयोग करने वाले नमूना ऐप से काम कर रहा हूं, यह 'कंटेनर का उपयोग करता है। रजिस्ट्रार (...' लाइनें लेकिन यह किसी भी कंटेनर का उपयोग नहीं करती है। रिवॉल्व ... कहीं भी। क्या कोई विशिष्ट जगह है कि 'कंटेनर। रिसेल्व ...' या 'ठीक है' के बाद बस ठीक है? –

+0

क्षमा करें, कंटेनर के बजाय, यह कर्नेल होना चाहिए, जहां कर्नल IKernel प्रकार है। –

7

मुझे आशा है कि आप उपयोग कर सकते हैं service overrides में कुछ भी देखते हैं।

पूर्व।

container.Register(
    Component.For<IMyService>() 
     .ImplementedBy<MyServiceImpl>() 
     .Named("myservice.default"), 
    Component.For<IMyService>() 
     .ImplementedBy<OtherServiceImpl>() 
     .Named("myservice.alternative"), 

    Component.For<ProductController>() 
     .ServiceOverrides(ServiceOverride.ForKey("myService").Eq("myservice.alternative")) 
); 

public class ProductController 
{ 
    // Will get a OtherServiceImpl for myService. 
    // MyServiceImpl would be given without the service override. 
    public ProductController(IMyService myService) 
    { 
    } 
} 
+0

यह आशाजनक दिखता है! –

+0

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

2

आमतौर पर डि कंटेनर रजिस्टर का पालन हल, समाधान करें और पैटर्न को छोड़ दें। रजिस्टर चरण के दौरान दो कदम हैं। सबसे पहले मैपिंग निर्दिष्ट करना है जैसा आप कर रहे हैं। दूसरा चरण नियमों को निर्दिष्ट करना है जो नियंत्रित करते हैं कि कहां इंजेक्ट करना है।

जब हम सजावटी का उपयोग कर क्रॉस कटिंग चिंताओं को संबोधित करने का प्रयास करते हैं तो यह समस्या बहुत आम है। इन परिस्थितियों में, आपके पास एक ही इंटरफेस को लागू करने वाले कई वर्ग (सजावटी) हैं।

संक्षेप में, हमें IModelInterceptorsSlector को लागू करने की आवश्यकता है जो आपको अनिवार्य कोड लिखने की अनुमति देता है जो तय करता है कि कौन से इंटरसेप्टर किस प्रकार या सदस्यों पर लागू होते हैं।

यह मार्क सेमैन द्वारा नेट बुक में निर्भरता इंजेक्शन पुस्तक में विस्तृत रूप से वर्णित है। अध्याय 9 अवरोध की तलाश करें या उपरोक्त इंटरफ़ेस की खोज करें।

मैं इस पर एक विशेषज्ञ नहीं हूं, लेकिन एक ही समस्या की तलाश कर रहा था और उपर्युक्त पुस्तक में जवाब पाया।

उम्मीद है कि इससे मदद मिलती है।

सादर Dev1

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