2011-12-05 10 views
6

मैं एक Autofac मॉड्यूल जो निम्नलिखित (कांट छांट) लोड ओवरराइड में तर्क दिया गया है:बंद करो Autofac मॉड्यूल पंजीकरण पहले से पंजीकृत घटकों

protected override void Load(ContainerBuilder builder) 
    { 
     foreach (var componentType in allTypesInAllAvailableAssemblies) // Set elsewhere 
     { 
      var handlerInterfaces = componentType.GetInterfaces().Where(i => i.IsClosedTypeOf(typeof(IMessageHandler<>))); 
      if (handlerInterfaces.Any()) 
       builder.RegisterType(componentType).As(handlerInterfaces); 
     } 
    } 

यह किसी भी वर्ग है कि अपने आप में एक संदेश हैंडलर वाणी की तलाश में है और सभी इमेजेज के खिलाफ इसे पंजीकृत करता है हैंडलर इंटरफेस इसे लागू करता है।

मैं क्या करना चाहता हूं घटक पंजीकृत है यदि यह पहले से ही पंजीकृत है। बोनस के रूप में, यह आदर्श होगा यदि मैं संदेश हैंडलर इंटरफेस (ओं) के खिलाफ हल करने के लिए मौजूदा पंजीकरण को अद्यतन कर सकता हूं, यदि यह पहले से नहीं है।

तर्क की खातिर यह है कि इस कोड के बाद अन्य सभी प्रकार के पंजीकरण किया गया है (संभव संदेश हैंडलर उम्मीदवारों सहित) चलेंगे

मैं में पंजीकरण हेरफेर के लिए AttachToComponentRegistration ओवरराइड का उपयोग किया है माना जा सकता है के लिए अतीत लेकिन ऐसा लगता है कि यह इस परिदृश्य में उपयोगी नहीं है।

क्या यह संभव है या क्या मुझे अपने डिजाइनरों और बल प्लगइन पर पुनर्विचार करना चाहिए ताकि वे स्पष्ट रूप से अपने हैंडलर घोषित कर सकें?

+0

क्या आपने AnyConcreteTypeNotAlreadyRegisteredSource क्लास का उपयोग करने का प्रयास किया है?देखें: http://stackoverflow.com/questions/3413660/ –

उत्तर

7
builder.RegisterType(componentType) 
    .As(handlerInterfaces) 
    .PreserveExistingDefaults(); 

काम जब तक आप संचालकों की सूची को हल करने शुरू होगा।

+0

दुर्भाग्य से मुझे हैंडलर की सूचियों की आवश्यकता है। जब सभी प्रकार के एक और स्वीप करने के बजाए एक प्रकार स्पष्ट रूप से पंजीकृत होता है तो मैं सभी हैंडलर इंटरफेस को देखने के लिए प्रेषित पंजीकरण को बदल देता हूं। सहायता के लिए चीयर्स - मैंने इसे स्वीकार कर लिया है क्योंकि यह पोस्ट किए गए प्रश्न का उत्तर देता है। – JRoughan

1

दुर्भाग्य से आप जो चाहते हैं उसे करने का एक शानदार तरीका नहीं है। ऑटोफैक कंटेनर, और इसके निर्माता, "ब्लैक बॉक्स" हैं जो आपको पहले से मौजूद चीज़ों पर एक अच्छा नज़र डालने नहीं देते हैं।

एक घटक को दो बार पंजीकृत करने में कोई हानि नहीं है, इसके अलावा आपके पंजीकरण ऑर्डर-निर्भर (बीएडी, बीएडी, बीएडी) हैं। दूसरी बार पंजीकरण करना नए पंजीकरण के साथ पुराने पंजीकरण को ओवरराइट करेगा।

मैं गंभीरता से इस कोड पर सवाल करता हूं, क्योंकि यह पूरी तरह से निर्भर करता है कि AllTypesInAllAvailableAssemblies कैसे प्रारंभ किया गया है। यदि यह वास्तव में आपके सिस्टम में हर प्रकार है, तो यह एक बकवास शूट है, जैसा कि एक आईडीस्पोजेबल कहता है। यदि आपके पास आईकोनफिगरेटर के कई अलग-अलग कार्यान्वयन हैं, तो आपके पास सीमित नियंत्रण होगा जिस पर कोई भी पंजीकृत हो जाता है, इस पर ध्यान दिए बिना कि आप पहले से पंजीकृत हैं या पंजीकरण को ओवरराइट करने की जांच कर रहे हैं या नहीं; यह पूरी तरह से निर्भर करता है कि सूची में कौन सी कक्षा पहले (या आखिरी) समाप्त होती है।

protected override void Load(ContainerBuilder builder) 
{ 
    foreach (var componentType in allTypesInAllAvailableAssemblies.OfType<Type>().Distinct()) // Set elsewhere 
    { 
     var handlerInterfaces = componentType.GetInterfaces().Where(i => i.IsClosedTypeOf(typeof(IMessageHandler<>))); 
     if (handlerInterfaces.Any()) 
      builder.RegisterType(componentType).As(handlerInterfaces); 
    } 
} 

यह गारंटी देगा कि componentType के प्रत्येक उदाहरण कभी नहीं देखा गया है:

केवल एक चीज मैं ऐसा करने के बारे में सोच सकता है एक छोटे से Linq का उपयोग सुनिश्चित करें कि आप प्रकार दर्ज कर रहे हैं की सूची अद्वितीय है बनाने के लिए है इस foreach पाश के दायरे के भीतर, पहले बिल्डर द्वारा। इसका मतलब यह है कि, यह एकमात्र मॉड्यूल है जो कंटेनर बनाने के लिए उपयोग किया जाता है, और प्रत्येक कंटेनर केवल एक बार बनाया गया है और कभी अपडेट नहीं किया गया है, सिस्टम में प्रत्येक घटक बिल्कुल किसी भी कंटेनर में एक बार पंजीकृत होगा। सामान्य इंटरफेस, जैसे IDISposable, IENumerable, IComparable, IComparer, आदि हल करने का प्रयास करने के लिए बेकार होने जा रहे हैं; वे उस इंटरफेस वाले अंतिम वर्ग के उदाहरण को हल करेंगे।

यदि आपको यह सत्यापित करना है कि एक इंटरफ़ेस कभी पंजीकृत नहीं हुआ है, या यह कोड एक कंटेनरबिल्डर को अद्यतन कंटेनर() को एक मौजूदा कंटेनर का उपयोग करते समय भी काम करता है, तो बस आप जो कर रहे हैं उसे रोकें क्योंकि आप निराशाजनक बनने वाले हैं गड़बड़ आप कभी भी ठीक से बनाए रखने में सक्षम नहीं होंगे।

+0

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

+0

सिस्टम में मौजूद कई इंटरफेस के साथ कोई समस्या नहीं है (वास्तव में इसकी उम्मीद है)। मौजूदा कंटेनरों या पंजीकरण की ऑर्डर निर्भरता का कोई अद्यतन भी नहीं है। मैंने शायद परिदृश्य को समझाया नहीं है और साथ ही मैं कर सकता हूं लेकिन यह उतना बुरा नहीं है जितना आप सोच रहे हैं। – JRoughan

+0

ओह, और allTypesInAllAvailableAssemblies केवल SO नमूना में मौजूद हैं। वास्तविक दुनिया में उपलब्ध प्रकारों को किसी अन्य वर्ग द्वारा प्रदान किया जाता है जिसमें कुछ स्मारक होते हैं। – JRoughan

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