2010-10-15 11 views
7

मैं मौजूदा विंडोज फॉर्म एप्लिकेशन में DI (Autofac के साथ) पेश करने की कोशिश कर रहा हूं।डीआई (ऑटोफैक): प्लग-इन प्रति एक अलग डी कंटेनर ठीक है?

इस एप्लिकेशन में एक बुनियादी प्लग-इन आर्किटेक्चर है जहां प्रत्येक प्लगइन अपना स्वयं का फॉर्म प्रदर्शित करता है। स्टार्टअप पर आवेदन स्कैन प्रकार है कि IPlugin को लागू करने के लिए पंजीकृत विधानसभाओं, और फिर सक्रिय हो जाता है इन का उपयोग कर Activator.CreateInstance:

public interface IPlugin 
{ 
    Form MainForm { get; } 
} 

मैं कर सकते हैं परिवर्तन इस दी ढांचा नहीं। इसका मतलब है, प्रत्येक प्लगइन वर्ग को गैर-डीआई माध्यमों के माध्यम से तुरंत चालू किया जाता है, और ऐसा लगता है कि मुझे प्रत्येक प्लगइन के लिए एक अलग डी कंटेनर बूटस्ट्रैप करना होगा।

मेरा प्रश्न है, एक अलग ContainerBuilder और प्रति प्लगइन कंटेनर बना रहा है ठीक है और अभी भी उचित रूप से कुशल है? (लगभग 10 अलग-अलग प्लगइन्स होंगे।) या पूरे आवेदन के लिए केवल एक डी कंटेनर होना चाहिए?

मैंने नीचे अपने वर्तमान समाधान का कुछ नमूना कोड प्रदान किया है।


using Autofac; 
using System.Windows.Forms; 

public class Plugin : IPlugin // instantiated by Activator 
{ 
    public Form MainForm { get; private set; } 

    public Plugin() // parameter-less constructor required by plugin framework 
    { 
     var builder = new ContainerBuilder(); 
     builder.RegisterModule(new Configuration()); 
     var container = builder.Build(); 

     MainForm = container.Resolve<MainForm>(); 
     //^preferred to new MainForm(...) because this way, I can take 
     // advantage of having dependencies auto-wired by the container. 
    } 
} 

internal class Configuration : Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
     builder.RegisterType<MainForm>().SingleInstance(); 
     // ... more plugin-specific registrations go here... 
    } 
} 

internal class MainForm : Form { /* ... */ } 

मैं भी यकीन है कि प्लगइन निर्माता में एक कंटेनर बनाने और फिर बस इसके बारे में भूल जाते हैं, लेकिन इसे छोड़ने पृष्ठभूमि में स्वत: तारों करने के लिए है कि क्या, ठीक है नहीं कर रहा हूँ?

उत्तर

7

आप कंटेनर उपयोग आदर्श रूप से Register Resolve Release pattern (आरआरआर) का पालन करना चाहिए। मुझे पता है कि आपने कहा था कि आप वर्तमान एक्टिवेटर को नहीं बदल सकते हैं। क्रिएट इंस्टेंस उपयोग, लेकिन यह अभी भी समझने में सहायक हो सकता है कि यह वास्तव में कैसे होना चाहिए।

यदि आपके पास उस बाधा नहीं है, तो केवल एक ही कंटेनर उदाहरण होना चाहिए, जो अभिभावक एप्लिकेशन द्वारा होस्ट किया गया हो। इसका उपयोग तब सभी प्लगइन लिखने के लिए किया जा सकता था। यह प्लगइन्स निर्भरताओं को साझा करने में सक्षम करेगा। यह एमईएफ द्वारा लिया गया मार्ग है, जो विस्तारशीलता परिदृश्यों को भी संबोधित करता है।

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

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

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

+0

उत्तर देने के लिए धन्यवाद, @ मार्क। अगर मैं आपको सही ढंग से समझता हूं, तो मेरा उदाहरण कोड आरआरआर पैटर्न का पालन करता है ... सही? (अपवाद के साथ कि मैं कंटेनर को रिलीज़ नहीं करता हूं, क्योंकि इसे रूट घटक 'मेनफॉर्म' के रूप में कम से कम जीवित रहने की आवश्यकता है। मुझे लगता है कि ऐसा करने का आदर्श तरीका प्लगइन को 'आईडीस्पोजेबल' और रिलीज़ करना होगा 'निपटान' विधि में कंटेनर।) – stakx

+2

आपके कोड में कुछ भी नहीं है जो बताता है कि आप आरआरआर का पालन नहीं करते हैं, लेकिन यह कहना मुश्किल है। किसी भी मामले में, ध्यान रखें कि सिंगलइंस्टेंस लाइफस्टाइल केवल कंटेनर-स्कॉप्ड सिंगलटन को परिभाषित करती है। यह एक असली सिंगलटन नहीं है, इसलिए आप मेनफॉर्म को इस तरह से साझा नहीं कर सकते हैं। –

0

मैं भी यकीन है कि प्लगइन निर्माता में एक कंटेनर बनाने और फिर बस इसके बारे में भूल जाते हैं, लेकिन इसे छोड़ने पृष्ठभूमि में स्वत: तारों करने के लिए है कि क्या, ठीक है नहीं कर रहा हूँ?

कई महीने बाद मेरे अपने प्रश्न को देखते हुए, मैं कहता हूं कि सिर्फ container भूल के बाद से (क) यह IDisposable है और इस तरह के रूप में व्यवहार किया जाना चाहिए, और, ठीक नहीं है हिम्मत (ख) कुछ घटकों 'जीवन काल कंटेनर से बंधे हैं, इस प्रकार कंटेनर का जीवनकाल स्पष्ट रूप से समाप्त होना चाहिए; इसे फॉर्म के Dispose विधि में या जब FormClosed ईवेंट ट्रिगर किया गया हो।