6

के साथ निंजा विधि-स्तर अवरोध मैंने इंटरसेप्शन के लिए ट्यूटोरियल में देखा है कि आप एक विधि को लक्षित कर सकते हैं और इसे रोक सकते हैं। अर्थात।पैरामीटर

Kernel.Bind<Foo>().ToSelf(); 
Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(), invocation => {}); 

प्रलेखन/ट्यूटोरियल क्या उदाहरण में क्या करना है कि विधि आप बीच में रोकने का प्रयास कर रहे हैं पैरामीटर को कवर नहीं करता अर्थात यदि ThrowsAnError एक पैरामीटर के रूप में एक स्ट्रिंग को स्वीकार कर लिया।

Kernel.Bind<Foo>().ToSelf(); 
Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(**param goes here**), invocation => {}); 

बाध्यकारी के समय मुझे पैराम तक पहुंच नहीं है इसलिए मैं सोच रहा था कि मैं इस गलत तरीके से जा रहा हूं या नहीं?

संपादित

Working example

उत्तर

3

मुझे लगता है कि आप गलत समझ रहे हैं क्या होता है। आपकी Foo ऑब्जेक्ट को एक सजावट के साथ प्रतिस्थापित किया गया है जिसमें इंटरसेप्टर होता है।

public class FooDecorator : Foo 
{ 
    private readonly Foo decorated; 

    public FooDecorator(Foo foo) { this.decorated = foo; } 

    public void ThrowsAnError(object param1, int param2) 
    { 
     // calls the decorated instance with supplied parameters 
     this.decorated.ThrowsAnError(param1, param2); 
    } 
} 

दूसरे शब्दों में, पैरामीटर आपूर्ति की जाती है हल हो जाने पर फू कहा जाता है, सजाया उदाहरण के लिए पर पारित हो जाएगा: यह एक साधारण उदाहरण है।

हालांकि हस्तक्षेप के साथ, यह सब कुछ अधिक अप्रत्यक्ष (और धीमी) है, लेकिन अवधारणा वही है। मुझे यह स्वीकार करना होगा कि मैं निनजेक्ट अवरोध से परिचित नहीं हूं, लेकिन शायद ऑब्जेक्ट पर Proceed विधि है। मुझे लगता है कि InterceptReplace<T> विधि का पहला तर्क एक प्रतिनिधि नहीं है इस तरह के रूप में Expression<Action<T>>

Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(), 
    invocation => 
    { 
     try 
     { 
      // calls the decorated instance with supplied parameters 
      invocation.Proceed(); 
     } 
     catch (Exception ex) 
     { 
      Kernel.Get<ILogger>().Log(ex); 
     } 
    }); 

अद्यतन

, लेकिन एक अभिव्यक्ति पेड़,: दूसरे शब्दों में, आप कुछ इस तरह करना चाहिए। इस विधि को वास्तव में नहीं कहा जाता है, लेकिन यह पता लगाने के लिए विश्लेषण किया जाता है कि किस विधि को रोकना है। दूसरे शब्दों में, चूंकि विधि को कभी नहीं कहा जाता है, इसलिए आप केवल किसी भी तर्क की आपूर्ति कर सकते हैं। चाल सी # कंपाइलर को यह जानने के लिए है कि किस विधि अधिभार (यदि कोई है) का उपयोग करने के लिए। इससे कोई फर्क नहीं पड़ता कि आप बकवास की आपूर्ति करते हैं। दोनों बहस संदर्भ प्रकार के होते हैं, तो यह शायद काम करेगा:

Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(null, null), 
+1

मैं देख रहा हूँ तुम कहाँ से आ रहे हैं, लेकिन मुझे लगता है कि ओ पी के रूप में है कि विधि के लिए बाध्य एक समस्या है जाएगा 'Kernel.InterceptReplace (foo => foo.ThrowsAnError(), ...); 'वहां प्रवेश करने के लिए तर्कों की आवश्यकता होगी, अन्यथा यह संकलित नहीं होगा क्योंकि ThrowsAnError को एन तर्कों की आवश्यकता है, आपके उदाहरण में आपको ऐसा लगता है कि मैं * सोचता हूं *। 'कर्नेल। इंटरसेप्ट रीप्लेस (foo => foo.ThrowsAnError (किसी भी तरह से संतुष्ट पैराम 1, किसी भी तरह से संतुष्ट पैरा 2), ...);' हालांकि मैं गलत हो सकता था। – Grofit

+1

ग्रोफिट सही है, 'foo.ThrowsAnError()' अभी भी पैराम को –

+1

@ मार्कवाल्श निर्धारित करने की उम्मीद करेगा: आह, मैं देखता हूं। मेरा अपडेट देखें। – Steven