2012-04-29 23 views
14

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

हालांकि मुझे यकीन नहीं है कि एक WPF एप्लिकेशन में एकता कहां रखें और कॉन्फ़िगर करें।

मुझे लगता है कि कंटेनर को विश्व स्तर पर पहुंच योग्य होना चाहिए, इसलिए शायद यह एप्लिकेशन क्लास पर जाना चाहिए। लेकिन क्या मुझे इसे स्थिर संपत्ति के रूप में बनाना चाहिए? क्या मुझे इसे एप्लिकेशन_स्टार्टअप() ईवेंट हैंडलर में कॉन्फ़िगर करना चाहिए?

उदाहरण के लिए:

/// <summary> 
/// Interaction logic for App.xaml 
/// </summary> 
public partial class App : Application 
{ 
    public static UnityContainer MyUnityContainer; 


    private void Application_Startup(object sender, StartupEventArgs e) 
    { 
     // instantiate and configure Unity 
    } 
} 

इस तरह से मैं स्थिर संपत्ति के माध्यम से आवेदन पत्र में किसी भी जगह से कंटेनर उपयोग करने में सक्षम हो जाएगा:

App.MyUnityContainer 

मुझे लगता है कि यह यह है, लेकिन मैं ऐसा करने के लिए एक ही रास्ता है मुझे यकीन नहीं है कि इस मुद्दे के लिए विशेष रूप से WPF ऐप्स के लिए बेहतर प्रथाएं हैं या नहीं।

उत्तर

8

Composition Root Pattern पर एक नज़र डालें। आप अपने स्टार्टअप इवेंट हैंडलर में इसे प्रारंभ करना चाहते हैं और शेष एप्लिकेशन के लिए इसके अस्तित्व को भूलना चाहते हैं।

आप Service Locator Pattern को लागू करने की कोशिश कर रहे हैं, जो इस समस्या के लिए कई is an inferior solution के अनुसार है।

+0

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

+1

@JoaoMilasch शीर्ष स्तर? पूर्ण रूप से। लेकिन शीर्ष स्तर एक खिड़की क्यों होगा, न कि ऐप क्लास? आपके मामले में, आपके पास एक विंडो है जो एक भंडार की आवश्यकता होती है, जिसे कन्स्ट्रक्टर इंजेक्शन के माध्यम से इंजेक्शन दिया जा सकता है। फिर आप कंटेनर को कॉल करने वाले ऐप के स्टार्टअप ईवेंट में मेनविंडो को हल कर सकते हैं। –

+0

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

5

मुझे जो कुछ निष्कर्ष निकाला गया है उसे पोस्ट करने दें और उम्मीद है कि इससे लोगों की मदद मिलेगी। अगर कुछ गलत है तो सही करें! : पी

मुझे लगता है कि हम कुछ इस तरह में विचार करना होता:

/// <summary> 
/// Interaction logic for App.xaml 
/// </summary> 
public partial class App : Application 
{ 
    private void Application_Startup(object sender, StartupEventArgs e) 
    { 
     UnityContainer myUnityContainer = new UnityContainer(); 
     //make sure your container is configured 
     myUnityContainer.RegisterType<ISomeDependency, SomeDependencyImplementation>(); 
     myUnityContainer.RegisterType<IMainWindow, MainWindow>(); 

     myUnityContainer.Resolve<IMainWindow>().Show(); 
    } 
} 

public partial class MainWindow : Window, IMainWindow 
{ 
    private ISomeDependency _someDependency; 

    public MainWindow(ISomeDependency someDependency) 
    { 
     _someDependency = someDependency; 
    } 
} 

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

+1

मुझे लगता है कि आप रजिस्टर के बजाय रजिस्टर टाइप चाहते हैं। –

+0

सुधार के लिए धन्यवाद @ जैकोब्रेवर –

+1

@ जोआओ मिलाशच एक हिस्सा गायब है और (मेरे लिए स्पष्ट नहीं है) कंटेनर को मुख्य रूप से "प्रचारित" कैसे किया जाता है, जैसा कि आप "ग्लोबल कॉन्फ़िगरेशन" कॉन्फ़िगरेशन द्वारा एएसपीनेट एमवीसी में कुछ भी कर सकते हैं। .DependencyResolver "। "हल करें" केवल तभी जांचें जब कंटेनर में सभी निर्भरताओं का संदर्भ हो। – stenly

1

यूनिटी कंटेनर के नए संस्करण के अनुसार, हमें इसे अपने स्वयं के उदाहरण को पंजीकृत करना होगा ताकि इसे कन्स्ट्रक्टर इंजेक्शन के माध्यम से मॉडल में देखा जा सके।

App.xaml.cs फ़ाइल:

protected override void OnStartup(StartupEventArgs e) 
{ 
     var unityIoC = new UnityContainer(); 
     unityIoC.RegisterTypes(AllClasses.FromAssembliesInBasePath(), WithMappings.FromMatchingInterface, WithName.Default); 
     unityIoC.RegisterInstance(typeof(IUnityContainer), unityIoC); 
} 

देखें मॉडल वर्ग

[InjectionConstructor] 
public MyViewModel(IUnityContainer container) 
{ 
} 

अब एकता कंटेनर दृश्य मॉडल में के लिए उपलब्ध होगा और हल करने के लिए इस्तेमाल किया जा सकता।