2013-12-14 4 views
20

मैं कैलिबर्न.मिक्रो और ऑटोफैक का उपयोग कर एक आवेदन पर काम कर रहा हूं।ऑटोफैक और फनक कारखानों

मेरी रचना जड़ में मैं अब Autofac के साथ एक समस्या का सामना करना पड़ रहा हूँ: मैं अपने FirstViewModel में दुनिया भर में इस्तेमाल IEventAggregator इंजेक्षन करने के लिए है, और एक दूसरे IEventAggregator है कि केवल इस FirstViewModel द्वारा इस्तेमाल किया जा करने के लिए और यह बच्चों के लिए है।

मेरा विचार दूसरे को Owned<IEA> के रूप में इंजेक्शन देना था, और यह काम करता है, कंटेनर आईईए का एक अलग उदाहरण प्रदान करता है।

public FirstViewModel(
    IEventAggregator globalEA, 
    IEventAggregator localEA, 
    Func<IEventAggregator, SecondViewModel> secVMFactory) {} 

समस्या आता है जब मैं SecondViewModel को घटना एग्रीगेटर्स प्रदान करने के लिए है।

द्वितीय दृश्य दृश्य बनाने के लिए मैं Func<IEA, SecondVM> के रूप में एक फैक्टरी विधि का उपयोग करता हूं। SecondViewModel के निर्माता निम्नलिखित है:

public SecondViewModel(IEventAggregator globalEA, IEventAggregator localEA) {}

मैं कंटेनर पंजीकृत एक के रूप में पहले इंजेक्षन करना चाहते हैं, और दूसरा Func<IEA, SecVM> की आईईए पैरामीटर हो जाएगा।

इस समारोह मैं कंटेनर में पंजीकृत है:

builder.Register<Func<IEventAggregator, SecondViewModel>>(
    c => 
     (ea) => 
     { 
      return new SecondViewModel(
       c.Resolve<IEventAggregator>(), 
       ea); 
     } 
); 

लेकिन जब यह FirstViewModel मैं निम्नलिखित त्रुटि मिलती से बुलाया जाता है:

An exception of type 'System.ObjectDisposedException' occurred in Autofac.dll but was not handled in user code

Additional information: This resolve operation has already ended. When registering components using lambdas, the IComponentContext 'c' parameter to the lambda cannot be stored. Instead, either resolve IComponentContext again from 'c', or resolve a Func<> based factory to create subsequent components from.

मैं कहाँ समस्या नहीं समझ सकता क्या आप कृपया मेरी मदद कर सकते हैं, मुझे क्या याद आ रही है?

धन्यवाद।

उत्तर

38

आप अपने FirstViewModel कन्स्ट्रक्टर के बाहर secVMFactory पर कॉल कर रहे हैं, इसलिए उस समय संकल्पऑपरेशन का निपटारा किया गया है और आपकी फैक्ट्री विधि में c.Resolve अपवाद फेंक देगा।

सौभाग्य से अपवाद संदेश बहुत वर्णनात्मक और आपको बता क्या करना है:

builder.Register<Func<IEventAggregator, SecondViewModel>>(c => { 
    var context = c.Resolve<IComponentContext>(); 
    return ea => { 
      return new SecondViewModel(context.Resolve<IEventAggregator>(), ea); 
    }; 
}); 
: c.Resolve बुला तो बजाय

When registering components using lambdas, the IComponentContext 'c' parameter to the lambda cannot be stored. Instead, either resolve IComponentContext again from 'c'

आप c से IComponentContext को हल करने और उपयोग करने वाले अपने कारखाने समारोह में करने की जरूरत है

+0

हाहा मैंने ऐसा करने की कोशिश की लेकिन मैंने इसे आंतरिक कार्य रखा, इसलिए मुझे एक ही त्रुटि मिल रही है! एक और प्रश्न +1 करें: क्या मुझे किसी भी वीएम ऑर्डर तत्काल रिफैक्टरिंग को रोकने के लिए हर पंजीकरण में ऐसा करना चाहिए? – Sergio

+0

यह आपकी आवश्यकताओं पर निर्भर करता है, आप हमेशा 'c.Resolve (); 'जब आप कंटेनर में' Func' पंजीकृत कर रहे हों या केवल उन मामलों में करें जहां आपको वास्तव में 'समाधान' करने की आवश्यकता है आपका कारखाना – nemesv

+0

आप पोस्ट में इस समस्या के बारे में अधिक पढ़ सकते हैं [ऑटोफैक में डेडलॉक का उत्सुक मामला] (http://www.continuousimprover.com/2015/01/the-curious-case-of-deadlock-in-autofac। एचटीएमएल) –

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