2014-05-01 4 views
10

के अंदर ऑटोफ़ैक निर्भरताओं को हल करना मैं ऑटोफ़ैक में नया हूं और वर्तमान में कुछ कोर F # सिस्टम को बूट करने के लिए अपने ऐप कॉन्फ़िगरेशन के अंदर कस्टम मॉड्यूल का उपयोग कर रहा हूं। कोड मैं उपयोग कर रहा हूँमॉड्यूल क्लास

var builder = new ContainerBuilder(); 
builder.RegisterType<DefaultLogger>().As<IDefaultLogger>(); 
builder.RegisterModule(new ConfigurationSettingsReader("autofac")); 
builder.Build(); 

है और मेरे एप्लिकेशन config अंदर मैं प्रासंगिक प्रणाली शुरू करने के लिए उचित तर्क है। मैं अपने मॉड्यूल के अंदर डिफॉल्ट लॉगर तक पहुंच प्राप्त करना चाहता हूं। मॉड्यूल आधार वर्ग के लिए मेटाडाटा मेरे पास उपलब्ध निम्न विकल्प हैं:

protected virtual void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration); 

protected virtual void AttachToRegistrationSource(IComponentRegistry componentRegistry, IRegistrationSource registrationSource); 

public void Configure(IComponentRegistry componentRegistry); 

protected virtual void Load(ContainerBuilder builder); 

मैं केवल लोड का उपयोग कर अब तक और मुझे लगता है कि मुझे प्रवेश पर प्राप्त करने के लिए अनुमति होगी बिल्डर पर किसी भी तरीकों नहीं देख सकते हैं सर्विस।

+0

इस http://stackoverflow.com/questions/23413211/autofac-cannot-resolve-dependency-in-module वाली डुप्लिकेट सवाल है? –

उत्तर

3

जवाब निकला अविश्वसनीय रूप से सरल होने के लिए। मैं बस अपना मॉड्यूल के कार्यान्वयन

public class LocalActorSystemModule : Module { 
    private IComponentContext m_ComponentContext; // A service for resolving dependencies required by this module 

    public LocalActorSystemModule(IComponentContext componentContext) { 
     m_ComponentContext = componentContext; 
    } 

करने के लिए एक निर्भरता के रूप में IComponentContext जोड़ा और AutoFac मेरे लिए IComponentContext इंजेक्षन करते हैं। इस तरह से मैं मॉड्यूल के अंदर आवश्यक किसी भी निर्भरता को हल कर सकता हूं।

+0

आप स्थानीयएक्टर सिस्टम सिस्टम को कैसे पंजीकृत करेंगे? –

+1

यह मेरे लिए काम नहीं किया। मैं मॉड्यूल निर्माता के माध्यम से IComponentContext इंजेक्शन, लेकिन जब मैं में इसका इस्तेमाल करने की कोशिश की 'यह हल नहीं कर सका क्या मैं इसे क्योंकि घटकों अभी तक पंजीकृत नहीं किया गया था चाहता था AttachToComponentRegistration'। – emragins

+0

यह केवल एक मॉड्यूल के लिए काम कर सकते हैं मॉड्यूल में ही पंजीकृत है और लोड करने के बाद (आवश्यक निर्भरता, उदा मॉड्यूल लोड किए गए हैं), अन्यथा आप असमर्थ संकल्प हैं। आईएमएचओ, आईसीओम्पोनेंट कॉन्टेक्स्ट को सेवाओं के पंजीकरण (स्वचालित रूप से) में इंजेक्शन दिया जाना चाहिए, लेकिन मॉड्यूल में उपयोग के लिए नहीं। मुझे लगता है कि व्यवहार वास्तव में अनुमानित नहीं है और मैं ऐसा करने की सिफारिश नहीं करता। मॉड्यूल वास्तव में लोड नहीं होने पर IComponentContext का उपयोग करने के बारे में सोचें ... लोड होने से पहले और बाद में परिणाम क्या होगा? बजाय सिर्फ पूरे IComponentContext पास करने का - – Beachwalker

6

जब autofac के साथ अपने मॉड्यूल के भीतर कुछ दर्ज की बजाय आप रजिस्टर विधि का उपयोग हो सकता है RegisterType विधि का उपयोग कर:

builder.Register(c => 
    { 
     IComponentContext ctx = c.Resolve<IComponentContext(); 
     IDefaultLogger logger = ctx.Resolve<IDefaultLogger>(); 
     ...do something with logger... 
     return ...return object you want to register...; 
    }); 
+1

यह वास्तव में उस परिदृश्य में मदद नहीं करता है जिसका मैं वर्णन कर रहा हूं। मैं समझता हूं कि मैं IComponentContext का उपयोग कर निर्भरताओं को हल कर सकता हूं लेकिन मुझे मॉड्यूल के अंदर एक तक पहुंच की आवश्यकता है। –

+0

आपको बाहरी दायरे में एक चर सेट करने के लिए यहां फोकस छोड़ने की अनुमति नहीं है (उसके उदाहरण में मॉड्यूल)। इस तरह आप केवल पंजीकरण के अंदर लॉग इन कर सकते हैं। वैसे भी, यह स्निपिट कंटेनर/संदर्भ का उपयोग करने का "सही तरीका" दिखाता है, इसलिए +1। हो सकता है कि जेसी जीवन स्कोप और एक कंटेनर एक लकड़हारा है और एक अन्य कंटेनर कि लकड़हारा इंजेक्शन जो अपने आप में पहले द्वारा प्रदान की मॉड्यूल को लोड करता है हो जाता है बनाता है कि उपयोग करने की आवश्यकता (हम्म, जिस तरह से जटिल लगता है)। – Beachwalker

2

का उपयोग करने के लिए अंगूठे का नियम प्रत्येक आईओसी/डी कंटेनर: एक बार हल करें! => फिर आपको अपने अनुरोधित ऑब्जेक्ट के लिए सभी निर्भरताओं का समाधान मिलता है। यदि आप कई बार हल करने का प्रयास करते हैं, तो अन्य ऑब्जेक्ट्स पंजीकृत करें (इस बीच) आप नरक में फंस गए हैं। वास्तव में। यदि आप विभिन्न स्थानों और समय बिंदुओं (केंद्रीय पंजीकरण से हल) पर विभिन्न उद्देश्यों के लिए वस्तुओं को पुनर्प्राप्त करना चाहते हैं, तो आप इसके बजाय Service Locator Pattern खोज रहे हैं (लेकिन इसे अक्सर Anti-Pattern के रूप में भी वर्णित किया जाता है)।

एक मॉड्यूल एक छोटा सा वर्ग है कि एक 'मुखौटा के पीछे संबंधित घटकों का एक सेट अप बंडल करने के लिए इस्तेमाल किया जा सकता है:

मॉड्यूल उद्देश्य संबंधित पंजीकरण (सशर्त) बंडल करने Autofac documentation में statet के रूप में है 'कॉन्फ़िगरेशन को सरल बनाने और परिनियोजन।

... इसलिए यदि वे सिर्फ पंजीकरण की राशि कर रहे हैं और कंटेनर अभी तक नहीं किया गया है का निर्माण आप को हल करने और एक (यहां तक ​​कि पहले से पंजीकृत) घटक तुरंत (रजिस्ट्रार पर एक विधि बुला छोड़कर उपयोग करने में सक्षम नहीं हैं खुद को OnActivate * हुक के माध्यम से या उदाहरण पंजीकरण का उपयोग करते समय, लेकिन मुझे लगता है कि यह आपके उदाहरण के लिए मामला नहीं है)। घटक सिर्फ पंजीकरण की स्थिति में हैं लेकिन पूरा संदर्भ हल करने के लिए तैयार नहीं है। यदि आप किसी अन्य मॉड्यूल में पंजीकरण को ओवरराइड करते हैं तो क्या होगा? तब आप अलग-अलग वस्तुओं को इंजेक्शन देते थे ... बुरा विचार। हो सकता है कि आपको अपने आवेदन डिजाइन पर पुनर्विचार करना चाहिए और कौन सी वस्तुओं में कौन सी ज़िम्मेदारियां हैं।

वैसे: लॉगिंग एक क्रॉस काटने की चिंता है जिसे अक्सर कन्स्ट्रक्टर/प्रॉपर्टी इंजेक्शन करने के बजाए एक अलग स्थिर फैक्ट्री या सेवा को कॉल करके "इंजेक्शन/हल किया जाता है" (उदाहरण के लिए Common.Logging का उपयोग देखें)।

public class MyModule : Module 
{ 
    private static readonly ILog Log = LogManager.GetLogger<MyModule>(); 

    protected override void Load(ContainerBuilder builder) 
    { 
     Log.Debug(msg => msg("Hello")); // log whatever you want here 
    } 
} 

तुम भी AOP पुस्तकालयों का उपयोग और मॉड्यूल में निर्भरता बुनाई (प्रतिबिंब का उपयोग) करने की कोशिश कर सकते हैं।लेकिन मुझे नहीं लगता कि मॉड्यूल में लॉग इन करने का प्रयास करना उचित है।

वैसे भी: @ mr100 पहले से ही पंजीकरण के दौरान सही उपयोग से पता चला है। वहां आप सक्रियण इत्यादि भी संभाल सकते हैं लेकिन मॉड्यूल के लिए लॉगिंग नहीं कर सकते हैं।

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