2012-02-22 5 views
8

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

उदाहरण वस्तु ग्राफ:

foo → ClassA → ClassB 
bar → ClassA → ClassB 

कक्षा C के निर्माता:

public class C 
{ 
    public C(ClassB foo, ClassB bar) { … } 
} 

तो मुझे यकीन है कि ClassBfoo साथ instantiated ClassB dependancy के रूप में आपूर्ति की जाती है कर सकता हूँ foo, और bar और नरक; bar?

बस कुछ पृष्ठभूमि के लिए, मैं था कुछ आवश्यकताओं को बदलने, तो मैं के साथ एक समग्र लिखने केवल भंडार

public class CompositeWriteRepository<T> : IAdd<T> 
{ 
    public CompositeWriteRepository(IAdd<T> foo, IAdd<T> bar, Func<T, bool> descriminator) { ... } 
    public Add(T entity) 
    { 
     if (descriminator(entity)) { 
      foo.Add(entity); 
     } else { 
      bar.Add(entity); 
     } 
    }   
} 
मजाक के साथ

एक लेख केवल भंडार (IAdd) की जगह की जरूरत है, वह पर्याप्त आसान था, मैं सिर्फ नामों का उपयोग इंजेक्ट कर सकता हूं:

kernel.Bind<IAdd<EntityType>>().To<fooRepository>().Named("foo"); 
kernel.Bind<IAdd<EntityType>>().To<barRepository>().Named("bar"); 

kernel.Bind<IAdd<EntityType>>().To<CompositeWriterRepository<EntityType>>() 
    .WithConstructorArgument("foo", x => x.Kernel.Get<IAdd<EntityType>>("foo") 
    .WithConstructorArgument("bar", x => x.Kernel.Get<IAdd<EntityType>>("bar"); 

समस्या तब होती है जब मैं असली भंडार का उपयोग करता हूं; foo और bar आखिरकार फाइलों को लिखते हैं ताकि उन्हें अलग-अलग फ़ाइल नामों की आवश्यकता हो। चूंकि वे StreamWriter रिपॉजिटरीज़ हैं, इसलिए उनकी निर्भरताओं में से एक वास्तव में दो अलग-अलग फ़ाइल नाम प्राप्त करता है।

string FileName → FileStreamWriterFactory → StreamRepository → CompositeRepository 

एक ही रास्ता मैं अब तक मिल गया है चीजों के निर्माण के लिए एक नामित FileName, FileStreamWriterFactory नाम पर, नामित StreamRepository × 2 (foo के लिए एक बार और एक बार bar के लिए) बनाने के लिए है। ऐसा लगता है कि बहुत काम का है, इसलिए मुझे आशा है कि एक बेहतर समाधान होगा।

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

समाधान
रेमो ग्लोर क्रेडिट प्राप्त करना चाहिए; वह शायद सबसे अच्छा अभ्यास है।

क्या मैं वास्तव में किया था एक नया विस्तार

public static bool WhenAnchester(this IRequest request, Func<IRequest, bool> conditions) 
{ 
    var parentContext = request.ParentContext; 
    if (parentContext == null) { 
      return false; 
    } 

    return conditions(parentContext.Request) || 
     parentContext.Request.WhenAnchester(conditions); 
} 

यह तो मुझे आसानी से नियंत्रित जो फ़ाइल जो भंडार में इंजेक्शन करते हैं बनाने था।

kernel.Bind<string>().ToConstant("Foo.txt") 
    .When(x => x.Target.Name == "filepath" && 
       x.WhenAnchester(t => t.Target != null && t.Target.Name == "Dest1")); 

kernel.Bind<string>().ToConstant("Bar.txt") 
    .When(x => x.Target.Name == "filepath" && 
       x.WhenAnchester(t => t.Target != null && t.Target.Name == "Dest2")); 

शायद एक बेहतर समाधान है, इसलिए मुझे दूसरों के लिए यह अनुशंसा नहीं करना चाहिए, लेकिन यह मेरे लिए अच्छा काम कर रहा है।

+1

डी कंटेनरों को विशेष कार्यान्वयन से निर्भरताओं को जोड़ना नहीं है, इसलिए कक्षाएं केवल इंटरफेस पर भरोसा करती हैं। और आप विपरीत चाहते हैं, जिस चीज को हम आईओसी विचारों से बचने के लिए प्रयास करते हैं। – zerkms

+0

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

उत्तर

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