26

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

+1

आप [पी एंड पी एंटरप्राइज़ लाइब्रेरी] (http://entlib.codeplex.com) पर एक नज़र डाल सकते हैं। वे कवर के तहत एकता का उपयोग कर रहे हैं और कंटेनर उपयोगकर्ता इंटरैक्शन के बिना शुरू किया गया है। –

+0

@ सेबेस्टियन, जो पूरी तरह से सच नहीं है प्रवेश-बिंदु एप्लिकेशन (उर्फ उपयोगकर्ता) को एक कंटेनर प्रारंभ करना है और एंटरप्राइज़ लाइब्रेरी एकता एक्सटेंशन पंजीकृत करना है। नीचे दिए गए उदाहरण के लिए मेरा उत्तर देखें। –

उत्तर

6

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

निर्भरता इंजेक्शन एंट्री-पॉइंट असेंबली की ज़िम्मेदारी है। फिर भी, यदि आपके पास डीआई की आवश्यकता वाले बहुत से वर्ग और असेंबली हैं, तो यह संभव है कि वे कुछ वर्गों/विधानसभाओं के लिए बाएं बंद हों और कार्य कठिन हो जाए।

समाधान एक

कॉन्फ़िगरेशन पर सम्मेलन का उपयोग करना। आप कक्षा FooIFoo इत्यादि को लागू करने के नियम के साथ चिपके रहते हैं। बहुत सारे डी ढांचे के पास परंपरा का उपयोग करके इसे स्थापित करने का साधन है।

समाधान दो

समाधान है, क्योंकि कभी कभी तुम इंजेक्शन की स्थापना parameterise करने की जरूरत है सभी समस्याओं का समाधान नहीं करता है ऊपर।

एक अंतरफलक IIocInstaller जहां कंटेनर (या बिल्डर पारित हो जाता है)

public interface IIocInstaller 
{ 
    void Setup(ContainerBuilder builder); 
} 

निर्मित: यहाँ कैसे मैं इस समस्या (विशेष रूप से उन विधानसभाओं MEF द्वारा लोड के लिए और इस AutoFac के लिए है) समाधान कर लिया है है बनाया गया एक विधानसभा विशेषता है कि झंडे विधानसभाओं डि ज़रूरत:

[AttributeUsage(AttributeTargets.Assembly)] 
public class ExportAssemblyAttribute : Attribute 
{ 
} 

प्रत्येक विधानसभा में, मैं एक वर्ग है कि डि सेट बनाने के लिए:

[assembly: ExportAssembly] 
namespace This.That 
{ 

    [Export(typeof(IIocInstaller))] 
    public class IocInstaller : IIocInstaller 
    { 
     public void Setup(ContainerBuilder builder) 
     { 
      .... 
     } 
    } 
} 

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

+0

सुझाव के लिए धन्यवाद। यह मुझे मेरे सोच पैटर्न से बाहर मिला। अब हम एक अलग सेटअप परियोजना शुरू कर रहे हैं। इस तरह कक्षा पुस्तकालय विभिन्न कार्यान्वयन का उपयोग कर सकते हैं। – Patrick

+0

@ पैट्रिक यह एक मुश्किल समस्या है। स्टेटिक कन्स्ट्रक्टर आवश्यक रूप से काम नहीं करते क्योंकि यह DI के लिए देर हो सकती है, खासतौर पर ऑटोफ़ैक जैसे दो चरण कंटेनर के लिए। – Aliostad

+0

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

1

कॉलिंग एप्लिकेशन से इसे करने से कॉलिंग एप्लिकेशन पर अधिक बोझ पड़ता है। प्रारंभिकरण को छोड़ने और परेशानी में आने का मौका छोड़ना।

मैं इसे कक्षा पुस्तकालय में करूँगा, उदाहरण के लिए एक स्थिर निर्माता में।

+2

यह एक बुद्धिमान विकल्प नहीं है। एंट्री पॉइंट एप्लिकेशन को कंटेनर का स्वामित्व और नियंत्रण होना चाहिए, यही कारण है कि एकता IUnityContainerExtensionConfigurator इंटरफ़ेस को कार्यान्वित करने में आसान बनाने के लिए एक्सटेंशन और यूनिटीकॉन्टेनर एक्सटेंशन बेस क्लास को पंजीकृत करने की अनुमति देती है। एक उदाहरण के लिए मेरा जवाब देखें। –

23

मुझे पता है कि एक उत्तर चुना गया है, हालांकि मुझे लगता है कि एकता का एक हिस्सा अनदेखा किया जा रहा है। चूंकि यह एक विशिष्ट एकता प्रश्न था, मैंने सोचा कि मैं यूनिटीकॉन्टेनर एक्सटेंशन बेस क्लास को इंगित करता हूं जो IUnityContainerExtensionConfigurator लागू करता है। यह एपीआई लाइब्रेरी के लिए एंट्री पॉइंट एप्लिकेशन के लिए आसान बनाने के लिए है जो कंटेनर का मालिक है, यह सुनिश्चित करने के लिए एक आसान तरीका है कि आपकी लाइब्रेरी कंटेनर के साथ सही तरीके से पंजीकृत हो, और एपीआई के मालिक को पंजीकृत होने की अनुमति मिलती है और किस तरह।

इस उद्देश्य के लिए माइक्रोसॉफ्ट एंटरप्राइज़ पुस्तकालयों द्वारा इसका उपयोग किया जाता है।

मैं एक सरल रूप में एक लॉगिंग पुस्तकालय का उपयोग करने के लिए जा रहा हूँ:

public class Bootstrapper : UnityBootstrapper 
{ 
    protected override void ConfigureContainer() 
    { 
     base.ConfigureContainer(); 

     Container.AddNewExtension<EnterpriseLibraryCoreExtension>(); 
     Container.AddNewExtension<LoggingUnityExtension>(); 
     // ... 
    } 

    // ... 
} 

अब वे पंजीकृत किया है उद्यम पुस्तकालय और के लिए एपीआई:

public class LoggingUnityExtension : UnityContainerExtension 
{ 
    protected override void Initialize() 
    { 
     Container.RegisterType<ILogger, Logger>(new ContainerControlledLifetimeManager()); 
    } 
} 

फिर प्रवेश बिंदु आवेदन करता है लॉगिंग लाइब्रेरी। इस विधि के साथ एंट्री-पॉइंट एप्लिकेशन के लिए यह बहुत आसान है, जो किसी लाइब्रेरी डेवलपर को लक्ष्य के रूप में होना चाहिए।

+1

लाइब्रेरी का संदर्भ देना चाहते हैं ताकि लोग आसानी से आपके उदाहरण का उपयोग कर सकें। क्या आपको काम करने के लिए 'EnterpriseLibraryCoreExtension' की आवश्यकता है? – ajbeaven

+0

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

0

ओ.के. परियोजना.आईओसी नामक एक लाइब्रेरी बनाएं। यहां एकता स्थापित करें। Ioc लाइब्रेरी में अन्य परतों का संदर्भ लें। और प्रस्तुति परत के लिए आईओसी पुस्तकालय। यूनिटीहेल्पर नाम की एक कक्षा बनाएं।

/// <summary> 
/// Bind the given interface in request scope 
/// </summary> 
public static class IocExtensions 
{ 
    public static void BindInRequestScope<T1, T2>(this IUnityContainer container) where T2 : T1 
    { 
     container.RegisterType<T1, T2>(new HierarchicalLifetimeManager()); 
    } 

    public static void BindInSingletonScope<T1, T2>(this IUnityContainer container) where T2 : T1 
    { 
     container.RegisterType<T1, T2>(new ContainerControlledLifetimeManager()); 
    } 
} 

/// <summary> 
/// The injection for Unity 
/// </summary> 
public static class UnityHelper 
{ 

    public static IUnityContainer Start() 
    { 
     var container = BuildUnityContainer(); 

     DependencyResolver.SetResolver(new Unity.Mvc4.UnityDependencyResolver(container)); 

     return container; 
    } 

    /// <summary> 
    /// Inject 
    /// </summary> 
    /// <returns></returns> 
    private static IUnityContainer BuildUnityContainer() 
    { 
     var container = new UnityContainer(); 

     // register all your components with the container here 
     // it is NOT necessary to register your controllers 

     // Database context, one per request, ensure it is disposed 
     container.BindInRequestScope<IMVCForumContext, MVCForumContext>(); 
     container.BindInRequestScope<IUnitOfWorkManager, UnitOfWorkManager>(); 

     //Bind the various domain model services and repositories that e.g. our controllers require   
     container.BindInRequestScope<ITopicService, TopicService>(); 

     container.BindInRequestScope<ITopicTagRepository, TopicTagRepository>(); 

     //container.BindInRequestScope<ISessionHelper, SessionHelper>(); 

     return container; 
    } 
} 

एमवीसीफ़ोरम परियोजना देखें। MvcForm.Ioc क्लास लाइब्रेरी है। पुस्तकालय को अन्य परत संदर्भ मिलते हैं। यूनिटीहेल्पर नामक केवल एक वर्ग है।

https://github.com/leen3o/mvcforum

मैं उम्मीद है कि इस वाट आप के लिए देख रहे हैं।