2014-07-23 6 views
7

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

यहां समस्या है - उपयोगकर्ता को इंटरसेप्टर जोड़ने के बारे में चिंता करने की आवश्यकता नहीं है। कंटेनर को इसे स्वयं जोड़ना चाहिए, इस पर ध्यान दिए बिना कि कौन और कहाँ घटक पंजीकृत है।

यह अब मैं क्या कर रहा है:

if(!container.Kernel.HasComponent(typeof(MyBaseComponent))) 
    container.Register(Component.For<MyComponent>() 
     .Interceptors(InterceptorReference 
     .ForType<MyComponentMethodInterceptor>()) 
     .SelectedWith(new MyComponentMethodSelector()).AtIndex(1)); 

MyComponentMethodSelector एक सरल IInterceptorSelector जो जांच करता है कि methodName एक मैं रोकना (इस स्थिति में एक MyComponentMethodInterceptor इसे करने के लिए जोड़ा जाता है) की जरूरत के बराबर होती है है।

जैसा कि आप देख सकते हैं कि यह जांच करेगा कि घटक पहले से ही पंजीकृत है या नहीं।

सवाल है - मैं अगर यह पहले से पंजीकृत है एक इंटरसेप्टर जोड़ने का एक तरीका है? दिमाग में आने वाली सबसे स्पष्ट पसंद IContributeComponentModelConstruction का उपयोग कर रही है, हालांकि उस बिंदु पर मैं इंटरसेप्टर को जो विधि जोड़ता हूं उसे चुनने में सक्षम नहीं हूं। या वहाँ है?

संपादित करें:

मैं एक छोटे से अधिक विशिष्ट किया जाना चाहिए था। मुझे केवल एक विशिष्ट विधि के लिए एक इंटरसेप्टर जोड़ने की जरूरत है। इसलिए मैं एक MyComponentMethodSelector का उपयोग क्यों कर रहा हूं। मैं IContributeComponentModel से अवगत हूं, और मैंने तब तक शुरुआत की जब तक मुझे एहसास हुआ कि विधि चयनकर्ता जोड़ने के लिए मेरे पास कोई रास्ता नहीं था।

+0

NeroS: आप एक सुविधा

public class InterceptionFacility : AbstractFacility { protected override void Init() { Kernel.ComponentRegistered += new Castle.MicroKernel.ComponentDataDelegate(Kernel_ComponentRegistration); } void Kernel_ComponentRegistration(string key, Castle.MicroKernel.IHandler handler) { if (typeof(IEventuallyRegistered).IsAssignableFrom(handler.ComponentModel.Implementation)) { handler.ComponentModel.Interceptors.Add(new InterceptorReference(typeof(EventuallyRegisteredInterceptor))); } } } 

तो सुविधा कंटेनर करने के लिए से पहले पंजीकरण अपने घटक के जोड़ सकते हैं या जब अपने घटक दर्ज की अपनी सुविधा घटना को याद करेंगे बनाने के द्वारा शुरू होगा क्या आपको यह पता लगाने का कोई मौका मिला कि आप जो चाहते थे उसे संभालने के लिए, मुझे इसके बारे में सुनने में दिलचस्पी होगी – samy

+0

मुझे दुर्भाग्य से नहीं मिला है। मुझे एक अलग परियोजना में फिर से सौंप दिया गया है, इसलिए यह वर्तमान में होल्ड पर है। हालांकि मैं इसे एक बिंदु पर वापस प्राप्त करूंगा। – NeroS

उत्तर

8

आप आसानी से कंपोनेंट मॉडेल निर्माण योगदानकर्ता के साथ एक घटक में कॉन्फ़िगरेशन जोड़ सकते हैं जिसे IContributeComponentModelConstruction लागू करके आपकी सेवा के लिए घटक मॉडल के निर्माण पर बुलाया जाता है।

मान लीजिए कि आप IEventuallyRegistered के किसी भी कार्यान्वयन के लिए एक इंटरसेप्टर जोड़ना चाहते हैं, और उपयोगकर्ता आप DefaultRegistration उपयोग करना चाहते हैं एक कस्टम घटक पंजीकृत नहीं किया है, तो:

public interface IEventuallyRegistered { void test(); } 
public class DefaultRegistration : IEventuallyRegistered { public void test() { } } 
public class EventuallyRegisteredInterceptor : IInterceptor 
{ 
    public void Intercept(IInvocation invocation) { invocation.Proceed(); } 
} 

internal class Program 
{ 
    private static void Main(string[] args) 
    { 
     var container = new Castle.Windsor.WindsorContainer(); 
     container.Register(Component.For<EventuallyRegisteredInterceptor>()); 
     container.Register(Component.For<IEventuallyRegistered>().ImplementedBy<DefaultRegistration>()); 
     // I'm not doing the optional registration, I just want to 
     // demonstrate upgrading a additional configuration 

     var t = container.Resolve<IEventuallyRegistered>(); 
     t.test(); 
    } 
} 

IContributeComponentModelConstruction इंटरफ़ेस लागू करके आप परिवर्तित करने देता है घटक मॉडल के विन्यास जब यह बनाई गई है:

public class RequireInterception : IContributeComponentModelConstruction 
{ 
    public void ProcessModel(IKernel kernel, ComponentModel model) 
    { 
     if (model.Services.Contains(typeof(IEventuallyRegistered))) 
     { 
      model.Interceptors.Add(new InterceptorReference(typeof(EventuallyRegisteredInterceptor))); 
     } 
    } 
} 

फिर registeri से पहले कंटेनर के घटक जोड़ने अपने घटक एनजी:

container.Kernel.ComponentModelBuilder.AddContributor(new RequireInterception()); 
container.Register(Component.For<IEventuallyRegistered>().ImplementedBy<DefaultRegistration>()); 

भले ही यह एक सुविधा, इस अनुशंसित नहीं है के साथ कर्नेल का ComponentRegistered घटना के माध्यम से यह करने के लिए संभव है; चूंकि इसे मूल उत्तर में शामिल किया गया था, इसलिए मैं इसे शामिल कर रहा हूं लेकिन मैं इसे नीचे दबा रहा हूं।,

container.AddFacility<InterceptionFacility>(); 
container.Register(Component.For<IEventuallyRegistered>().ImplementedBy<DefaultRegistration>()); 
+1

मैं दृढ़ता से 'IContributeComponentModelConstruction' समाधान का सुझाव दूंगा। कर्नेल घटनाओं का मतलब 'घटक मॉडेल' –

+0

को संशोधित करने के लिए नहीं है, मैंने जो सोचा, पुष्टि करने के लिए धन्यवाद :) – samy

+0

@KrzysztofKozmic मैंने – samy

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