2010-03-11 11 views
7

मेरा मानना ​​है कि इस प्रश्न को कुछ या अन्य तरीकों से पूछा गया है लेकिन मुझे अभी तक यह नहीं मिल रहा है।मैन्युअल DI को गहरे ऑब्जेक्ट ग्राफ़ और कई निर्भरताओं के साथ ठीक से कैसे करें

हम एक जीडब्ल्यूटी परियोजना करते हैं और मेरे प्रोजेक्ट लीडर ने जीआईएन/गुइस को डी फ्रेमवर्क के रूप में उपयोग करने की अनुमति नहीं दी है (नए प्रोग्रामर इसे समझने वाले नहीं हैं, उन्होंने तर्क दिया) इसलिए मैं मैन्युअल रूप से DI करने की कोशिश करता हूं।

अब मुझे गहरे ऑब्जेक्ट ग्राफ के साथ समस्या है। यूआई से वस्तु पदानुक्रम इस तरह दिखता है:

AppPresenter-> DashboardPresenter-> GadgetPresenter-> GadgetConfigPresenter

वस्तु पदानुक्रम पेड़ GadgetConfigPresenter रास्ता CustomerRepository, ProjectRepository, MandatorRepository, आदि

जैसे कुछ निर्भरता है

तो गैजेट प्रायोजक जो गैजेट कॉन्फिग प्रस्तुतकर्ता बनाता है, में भी इन निर्भरताओं और ऐप के प्रवेश बिंदु तक, जो ऐप प्रस्तुतकर्ता बनाता है।

  • क्या यह तरीका मैन्युअल DI को काम करना चाहिए?
  • इसका मतलब यह नहीं है कि मैं बूट समय पर सभी निर्भरताओं को बना देता हूं, मुझे उनकी आवश्यकता नहीं है?
  • जीआईएन/गुइस जैसे डीआई फ्रेमवर्क मुझे यहां मदद करेंगे?
+2

समस्या की तरह लगता है कि आपकी परियोजना किसी भी चीज़ से अधिक है। आप एक तकनीक का उपयोग नहीं कर सकते क्योंकि एक नया प्रोग्रामर इसे समझ नहीं पाएगा? क्या समझना है उन्हें दस्तावेज और प्रशिक्षण के बारे में क्या? –

+0

@matt: वह नई प्रौद्योगिकियों के लिए काफी अनिच्छुक है और उनका मानना ​​है कि एक नए प्रोग्रामर को इस परियोजना में जावा से पीएचपी पुल की तरह बहुत कुछ सीखना होगा और फिर डीआई दृश्यों के पीछे सिर्फ कुछ जादू है जो उन्हें नहीं मिलेगी। मुझे वास्तव में ऐसा नहीं लगता .... यदि डीआई फ्रेमवर्क एकमात्र समाधान है तो मैं उसे मनाने के लिए फिर कोशिश करूंगा लेकिन मुझे वास्तव में दिलचस्पी होगी अगर यह मैन्युअल रूप से किया जाता है। – Fabian

+1

मैं इस चर्चा के करीब आने की सलाह दूंगा "इस मैनुअल वायरिंग-अप कार्य को हमें कोड में करने की ज़रूरत है, और इसकी तुलना करें कि आईओसी कंटेनर का उपयोग करके कितना आसान है" –

उत्तर

8

आप लिखते हैं कि

GadgetPresenter जो बनाता है GadgetConfigPresenter [।]

के बजाय सीधे GadgetConfigPresenter उदाहरणों, GadgetPresenter चाहिए take a dependency on an Abstract Factory कि इसके लिए GadgetConfigPresenter उदाहरण बना सकते हैं का निर्माण। यह कारखाने में GadgetConfigPresenter की आंतरिक निर्भरताओं को धक्का देता है।

निर्माता इंजेक्शन सभी तरह का उपयोग करना, अपने गरीब आदमी की डि तारों (सी # वाक्य रचना के लिए क्षमा याचना) कुछ इस तरह दिखना चाहिए:

var customerRepository = new CustomerRepository(/*...*/); 
var projectRepository = new ProjectRepository(/*...*/); 
var mandatorRepository = new MandatorRepository(/*...*/); 

var gadgetConfigPresenterFactory = 
    new GadgetConfigPresenterFactory(
     customerRepository, 
     projectRepository, 
     mandatorRepository); 

var gadgetPresenter = new GadgetPresenter(gadgetConfigPresenterFactory); 
var dashboardPresenter = new DashboardPresenter(gadgetPresenter); 
var appPresenter = new AppPresenter(dashboardPresenter); 

सूचना कैसे हम अक्सर निर्भरता श्रृंखला तोड़ने , यह सुनिश्चित करना कि प्रत्येक उपभोक्ता के लिए निर्भरता की संख्या कभी भी बड़ी न हो।

सिद्धांत रूप में, इसका मतलब है कि आपको बूट समय पर सभी निर्भरताओं को बनाना होगा, जब तक आप lazy loading strategy लागू नहीं करते।

लाइफटाइम के प्रबंधन जैसी चीजें बिल्कुल ऐसी चीज हैं जहां एक डी कंटेनर बहुत उपयोगी हो सकता है, लेकिन following DI patterns and principles द्वारा पूरे एप्लिकेशन को लिखना पूरी तरह से संभव है।

सब कुछ, हालांकि, मैं अभी भी एक डी कंटेनर की सिफारिश करता हूं यदि संभव हो तो।

0

आप संदर्भ इंटरफेस का उपयोग कर DI कर सकते हैं। यह कठिन नहीं है, और काफी सीधे आगे है।

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

यह एक उदाहरण है जहां मैं मान रहा हूं कि AppPresenter + DashboardPresenter एक पैकेज में है और एक "संदर्भ" की आवश्यकता है, जबकि गैजेट प्रतिनिधि और गैजेट कॉन्फिग प्रतिनिधि दूसरे पैकेज में है और उसे "संदर्भ" की आवश्यकता है। संदर्भों की संख्या, और उन्हें कैसे संभालना है पूरी तरह से उपयोगकर्ता के लिए है।

/** 
* The dependencies that need to be injected for package1 
*/ 
public interface SomePackageContext { 
    GadgetPresenter getGadgetPresenter(); 
    GadgetConfigPresenter getGadgetConfigPresenter(); 
} 

/** 
* The dependencies that need to be injected for package2 
*/ 
public interface OtherPackageContext { 
    // These methods can take arguments.. 
    AppPresenter getAppPresenter(Args..); 
    DashboardPresenter getDashboardPresenter(Args..); 
} 

/** 
* All of the DI needed in our project. 
* 
* <p>We don't need the two interfaces above, we can put 
* everything in this interface if we have a small 
* project where layering is not a big issue. 
*/ 
public interface PresenterContext 
    extends SomePackageContext, OtherPackageContext { 
} 


public class MockPresenterContext implements PresenterContext { 
    ... 
} 

public class RealPresenterContext implements PresenterContext { 
    // This is similar to bind(...) in guice 
    public AppPresenter getAppPresenter(Args..) { 
    return new AppPresenter(this, otherargs...); 
    } 
    public DashboardPresenter getDashboardPresenter(Args..) { 
    return new DashboardPresenter(this, otherargs...); 
    } 
    public GadgetPresenter getGadgetPresenter() { 
    return new GadgetPresenter(this); 
    } 
    public GadgetConfigPresenter getGadgetConfigPresenter() { 
    return new GadgetConfigPresenter(); 
    } 
} 

public class DashboardPresenter { 

    // @Inject 
    private final GadgetPresenter gadgetPresenter; 

    /* 
    * We inject everything using the SomePackageContext. 
    */ 
    public DashboardPresenter(SomePackageContext ctxt) { 
    this.gadgetPresenter = ctxt.getGadgetPresenter(); 
    } 
} 
संबंधित मुद्दे