2012-08-10 6 views
17

मैं यूनिटी इंटरसेप्टर सीखने की कोशिश कर रहा हूं और मुझे इसका कड़ी मेहनत हो रही है। ,आईएमआईइंटरफेस को सभी कॉलों को रोकने के लिए एकता का उपयोग करें। कुछ विधि

public class SpecificClass1 : IMyInterface 
{ 
    public void SomeMethod() 
    { 
     Console.WriteLine("Method Called"); 
    } 
} 

मैं कहने का एक तरीका रहा हूँ:

मैं इस तरह एक अंतरफलक है कहते हैं:

public interface IMyInterface 
{ 
    void SomeMethod(); 
} 

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

यह क्लैस का गैर-गणना है जो मुझे परेशान कर रहा है ई। (यदि आप अपने सभी वर्गों का आकलन कर सकते हैं तो बहुत सारे उदाहरण हैं।)

मैंने टाइप इंटरसेप्शन के बारे में पढ़ा है, लेकिन मुझे यह पता लगाना प्रतीत नहीं होता कि मैं क्या कर रहा हूं।

वहां कोई भी एकता विशेषज्ञ जानता है कि मैं क्या कर रहा हूं?

उत्तर

0

हस्तक्षेप की स्थापना के लिए कई क्रियाएं शामिल हैं। अवरुद्ध प्रकार, नीतियों और हैंडलर की विन्यास।

सबसे पहले स्थितियों के प्रकार के बारे में सामान्य विवरण के लिए Using Interception in Applications देखें जहां इंटरसेप्शन समर्थित है (उदाहरण के लिए या डी कंटेनर के बिना)। फिर समर्थित प्रकार इंटरसेप्टर के बारे में अधिक जानकारी के लिए Type Interception देखें। विशेष रूप से ध्यान दें कि आपकी कक्षा के प्रकार के साथ किस इंटरसेप्टर का उपयोग किया जा सकता है (अन्यथा हैंडलर कभी ट्रिगर नहीं करेंगे)।

जब आपने तय किया है कि किस इंटरसेप्टर का उपयोग करना है, इसे कॉन्फ़िगर करें और ऊपर दिए गए लिंक के अनुसार पर्याप्त कॉल हैंडलर बनाएं। यदि आपको अभी भी इस बिंदु पर परेशानी है, तो एक और विस्तृत प्रश्न पोस्ट करें। यदि आप पहले ही ऐसा कर चुके हैं, तो कृपया कॉन्फ़िगरेशन और कोड को "क्लैस के गैर-गणना" के रूप में पोस्ट करें, जो वास्तव में आप जो पूछ रहे हैं उसके बारे में कोई संकेत नहीं देते हैं। क्या आप किसी भी मौके से "गणना" के साथ मतलब करते हैं कि आप एक विशेषता-संचालित नीति असाइन करते हैं और जो भी आप चाहते हैं उसे हासिल करने में असमर्थ हैं?

18

आप InterceptionBehavior बना सकते हैं और फिर इसे विशिष्ट क्लास पर पंजीकृत कर सकते हैं। आप Invoke में क्रियान्वित करने के तरीकों पर फ़िल्टर कर सकते नोट के माध्यम से IMethodInvocation input

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.Practices.Unity; 
using Microsoft.Practices.Unity.InterceptionExtension; 
using NUnit.Framework; 

namespace UnitTests 
{ 
    [TestFixture] 
    public class ForTest 
    { 
     [Test] 
     public void Test() 
     { 
      IUnityContainer container = new UnityContainer().AddNewExtension<Interception>(); 
      container.RegisterType<IMyInterface, SpecificClass1>(
       new Interceptor<InterfaceInterceptor>(), 
       new InterceptionBehavior<MyInterceptionBehavior>()); 
      var myInterface = container.Resolve<IMyInterface>(); 
      myInterface.SomeMethod(); 
     } 
    } 

    public interface IMyInterface 
    { 
     void SomeMethod(); 
    } 

    public class SpecificClass1 : IMyInterface 
    { 
     #region IMyInterface 

     public void SomeMethod() 
     { 
      Console.WriteLine("Method Called"); 
     } 

     #endregion 
    } 

    public class MyInterceptionBehavior : IInterceptionBehavior 
    { 
     public bool WillExecute 
     { 
      get { return true; } 
     } 

     #region IInterceptionBehavior 

     public IEnumerable<Type> GetRequiredInterfaces() 
     { 
      return Enumerable.Empty<Type>(); 
     } 

     public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext) 
     { 
      IMethodReturn result = getNext()(input, getNext); 
      Console.WriteLine("Interception Called"); 
      return result; 
     } 

     #endregion 
    } 
} 

कंसोल आउटपुट

Method Called 
Interception Called 

अधिक के बारे में Interception with Unity

9

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

public class UnityInterfaceInterceptionRegisterer : UnityContainerExtension 
{ 
    private List<Type> interfaces = new List<Type>(); 
    private List<IInterceptionBehavior> behaviors = 
     new List<IInterceptionBehavior>(); 

    public UnityInterfaceInterceptionRegisterer(Type interfaceType, 
     IInterceptionBehavior interceptionBehavior) 
    { 
     interfaces.Add(interfaceType); 
     behaviors.Add(interceptionBehavior); 
    } 

    public UnityInterfaceInterceptionRegisterer(Type[] interfaces, 
     IInterceptionBehavior[] interceptionBehaviors) 
    {    
     this.interfaces.AddRange(interfaces); 
     this.behaviors.AddRange(interceptionBehaviors); 

     ValidateInterfaces(this.interfaces); 
    } 

    protected override void Initialize() 
    { 
     base.Container.AddNewExtension<Interception>(); 

     base.Context.Registering += 
      new EventHandler<RegisterEventArgs>(this.OnRegister); 
    } 

    private void ValidateInterfaces(List<Type> interfaces) 
    { 
     interfaces.ForEach((i) => 
     { 
      if (!i.IsInterface) 
       throw new ArgumentException("Only interface types may be configured for interface interceptors"); 
     } 
     ); 
    } 

    private bool ShouldIntercept(RegisterEventArgs e) 
    { 
     return e != null && e.TypeFrom != null && 
       e.TypeFrom.IsInterface && interfaces.Contains(e.TypeFrom); 
    } 

    private void OnRegister(object sender, RegisterEventArgs e) 
    { 
     if (ShouldIntercept(e)) 
     { 
      IUnityContainer container = sender as IUnityContainer; 

      var i = new Interceptor<InterfaceInterceptor>(); 
      i.AddPolicies(e.TypeFrom, e.TypeTo, e.Name, Context.Policies); 

      behaviors.ForEach((b) => 
       { 
        var ib = new InterceptionBehavior(b); 
        ib.AddPolicies(e.TypeFrom, e.TypeTo, e.Name, Context.Policies); 
       } 
      ); 
     } 
    } 
} 

तो फिर तुम यह इतना की तरह इस्तेमाल कर सकते हैं:

तो इस मामले में कंटेनर विस्तार कैसा दिखेगा

IUnityContainer container = new UnityContainer() 
    .AddExtension(new UnityInterfaceInterceptionRegisterer(
     new Type[] { typeof(IMyInterface), 
        typeof(IMyOtherInterface) }, 
     new IInterceptionBehavior[] { new MyInterceptionBehavior(), 
             new AnotherInterceptionBehavior() } 
     )); 

container.RegisterType<IMyInterface, SpecificClass1>(); 

var myInterface = container.Resolve<IMyInterface>(); 
myInterface.SomeMethod(); 

अब जब इंटरफ़ेस पंजीकृत किया गया है उचित अवरोधन नीतियों भी हो जाएगा कंटेनर में जोड़ा गया। तो इस मामले में यदि पंजीकृत इंटरफ़ेस IMYInterface या IMyOtherInterface प्रकार है तो नीतियों को इंटरफ़ेस अवरोध के लिए सेटअप किया जाएगा और इंटरसेप्शन व्यवहार MyInterceptionBehavior और AnotherInterceptionBehavior भी जोड़ा जाएगा।

ध्यान दें कि एकता 3 (इस प्रश्न/उत्तर के बाद जारी) ने Registration by Convention सुविधा जोड़ा जो यह एक्सटेंशन कर सकता है (कोई कस्टम कोड लिखने के बिना)। Developer's Guide to Dependency Injection Using Unity:

var container = new UnityContainer(); 

container.AddNewExtension<Interception>(); 
container.RegisterTypes(
    AllClasses.FromLoadedAssemblies().Where(
     t => t.Namespace == "OtherUnitySamples"), 
    WithMappings.MatchingInterface, 
    getInjectionMembers: t => new InjectionMember[] 
    { 
     new Interceptor<VirtualMethodInterceptor>(), 
     new InterceptionBehavior<LoggingInterceptionBehavior>() 
    }); 
से एक उदाहरण
संबंधित मुद्दे

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