2012-08-16 6 views
13

मेरे एप्लिकेशन में कई बैक-एंड असेंबली (एक इकाई फ्रेमवर्क डेटा रिपोजिटरी परत समेत) शामिल हैं जो कई फ्रंट-एंड असेंबली (विंडोज सेवा सहित) एक एमवीसी 3 वेब अनुप्रयोग)।मल्टी-स्तरीय एप्लिकेशन में निनजेक मॉड्यूल का पता लगाने के लिए

निनजेक्ट बाध्यकारी प्रक्रिया की मेरी समझ यह है कि इंजेक्शन योग्य प्रकारों वाली प्रत्येक असेंबली में निनजेक्ट मॉड्यूल भी होना चाहिए जो इन प्रकारों के लिए डिफ़ॉल्ट बाइंडिंग को परिभाषित करता है। परिभाषित मॉड्यूल का सेट उपभोग करने वाले असेंबली के निनजेक कर्नेल में लोड किया जाएगा।

हालांकि, मैं समस्याओं में भाग रहा हूं, क्योंकि आवश्यक बाध्यकारी दायरा हमेशा सुसंगत नहीं होता है। उदाहरण के लिए, मेरी MVC परियोजना जबकि Windows सेवा एक ही कक्षा InThreadScope को बांधता है, जिसे संदर्भ InRequestScope करने के लिए बाध्य करने की जरूरत है।

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

क्या मल्टी-स्तरीय एप्लिकेशन में मॉड्यूल स्थित होना चाहिए और परियोजनाओं के बीच अंतर को बाध्य करने की मेरी आवश्यकता के साथ मैं इसे कैसे सुलझ सकता हूं?

अपने सुझाव के लिए

बहुत धन्यवाद,

टिम

+0

यह भी देखें http://stackoverflow.com/questions/1699197/how-do-you-organise-your-ninject-modules (आईआईआरसी यह क्यू एक डुप्लिकेट है लेकिन यह अब मुझे सबसे अच्छा मिला है) –

+0

धन्यवाद रूबेन। आप सही हैं कि इन दो सवालों के बीच बहुत कुछ आम है। मैं विशेष रूप से असेंबली के समर्थन में रहने वाले मॉड्यूल में रनटाइम पैरामीटर को पारित करने के आपके सुझाव को पसंद करता हूं - बहुत लचीला। –

+0

हम्म; यह कुछ समय पहले (किसी भी तरह से मेरे जवाब को पंप करने की कोशिश नहीं कर रहा था)। मैं सचमुच मतलब * पासिंग पैरामीटर * दिन में वापस आ सकता था - आम तौर पर मैं जितना संभव हो इंटरफेस के माध्यम से ऐसा करने की कोशिश करता हूं। इसके अलावा, यह http://manning.com/seemann से पहले था, जो डीआई आर्किटेक्चर में नाटकीय रूप से परेशान पाए जाने वाले प्रश्नों की संख्या को कम करता है - डीफ रन इसे कोई प्रश्न नहीं पूछता है। –

उत्तर

12

एक आवेदन के साथ समाधान के लिए, सामान्य सलाह है कि आप अपने कंटेनर को एप्लिकेशन प्रोजेक्ट (अपना वेब ऐप, या वेब सेवा प्रोजेक्ट) में पंजीकृत करें। एक वेब अनुप्रयोग के लिए यह आम तौर पर Global.asax Application_Start होगा। इस स्थान पर आप सब कुछ एक साथ तार डि शब्दावली में Composition Root कहा जाता है।

एक बहु आवेदन समाधान के साथ

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

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

इस तरह की एक बात यह है कि इस प्रकार दिखाई देंगे:

// MVC Composition root 
public static void Bootstrap() 
{ 
    var container = new Container(); 

    // Default registrations 
    BusinessLayerBootstrapper.Bootstrap(container); 

    // Application specific registrations 
    container.Bind<IUserContext>().To<AspNetUserContext>(); 

    DependencyResolver.Current = 
     new ContainerDependencyResolver(container); 
} 

// Windows Service Composition root 
public static void Bootstrap() 
{ 
    var container = new Container(); 

    // Default registrations 
    BusinessLayerBootstrapper.Bootstrap(container); 

    // Application specific registrations 
    container.Bind<IUserContext>().To<SystemUserContext>() 
     .SingleScoped(); 

    // Store somewhere. 
    Bootstrapper.Container = container; 
} 

// In the BL bootstrap assembly 
public static class BusinessLayerBootstrapper 
{ 
    public static void Bootstrap(Container container) 
    { 
     container.Bind<IDepenency>().To<RealThing>(); 
     // etc 
    } 
} 

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

यह भी ध्यान दें कि मैं केवल (Ninject) मॉड्यूल का उपयोग करने के बजाय स्थिर Bootstrap() विधि को कॉल कर रहा हूं। मैंने अपना जवाब ढांचे से स्वतंत्र रखने की कोशिश की, क्योंकि आपका प्रश्न सामान्य है और सलाह सभी डी ढांचे के लिए समान होगी। हालांकि, निश्चित रूप से आप निंजा मॉड्यूल सुविधा का उपयोग कर सकते हैं यदि आप चाहते हैं।

6

scoping के बारे में एक MVC आवेदन एक खिड़कियों सेवा से एक अलग CompositionRoot की जरूरत है। मेरा सुझाव है कि आप जितना संभव हो उतना और अन्य सभी बाइंडिंग (उन भागों जो आवेदन नास्तिक हैं के लिए) सीधे MVC या WindowsService परियोजना के CompositionRoot में सुविधा मॉड्यूल से व्यवस्थित करने के लिए प्रयास करें।

एक और बहुत अच्छा तरीका सम्मेलनों के एक आम समूह को परिभाषित करना है जो आपको कुछ पंक्तियों में सबसे बाध्यकारी चिंताओं को व्यक्त करने में मदद करता है। इसलिए आपकी ऐप्लिकेशन बाइंडिंग के लिए निम्न हो सकता है:

MVC अनुप्रयोग

Bind(c => c.FromAssemblyContaining<IRepository>() 
      .SelectAllClasses() 
      .InheritedFrom<IRepository>() 
      .Configure(b => b.InRequestScope())); 

आपका Windows सेवा अनुप्रयोग

Bind(c => c.FromAssemblyContaining<IRepository>() 
      .SelectAllClasses() 
      .InheritedFrom<IRepository>() 
      .Configure(b => b.InThreadScope())); 

एक सुविधा उन्मुख संरचना के साथ संयुक्त देखने का मेरी बात में सम्मेलन दृष्टिकोण है सबसे साफ

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