Unity The Custom Attribute Matching Rule

在声明式编程流行的今天,对于AOP中许多附加功能我们往往会通过声明一个Attribute更为直观的展示。比如需要添加一个LogHandler,那就定义一个LogSupportAttribute。Unity提供了自定义Attribute的匹配规则类型CustomAttributeMatchingRule。看一个简单示例:

 1 public class MyObject
 2 {
 3   [LogSupport]
 4   public virtual void DoWork()
 5   {
 6 
 7   }
 8 
 9   public virtual void DoWork2()
10   {
11 
12   }
13 }
14 
15 [AttributeUsage(AttributeTargets.Method)]
16 public sealed class LogSupportAttribute : Attribute
17 {
18 
19 }
20 
21 public sealed class Log4NetHandler : ICallHandler
22 {
23   #region ICallHandler Members
24 
25   public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
26   {
27     Console.WriteLine(input.MethodBase.Name);
28 
29     return getNext()(input, getNext);
30   }
31 
32   public Int32 Order { get; set; }
33 
34   #endregion
35 }
36 
37 IUnityContainer unityContainer = new UnityContainer();
38 
39 unityContainer.LoadConfiguration();
40 unityContainer.Configure<Interception>()
41   .AddPolicy(“CustomAttributeMatchingRule”)
42   .AddMatchingRule(new CustomAttributeMatchingRule(typeof(LogSupportAttribute), true))
43   .AddCallHandler<Log4NetHandler>();
44 unityContainer.RegisterType<MyObject>(
45   new Interceptor<VirtualMethodInterceptor>(),
46   new AdditionalInterface<INotifyPropertyChanged>(),
47   new InterceptionBehavior<PolicyInjectionBehavior>()
48 );
49 
50 MyObject myObject = unityContainer.Resolve<MyObject>();
51 
52 myObject.DoWork();

在上面的示例代码中定义了LogSupportAttribute,MyObject的DoWork函数添加了它,而DowWork2函数没有。执行后可以发现只有DoWork函数被拦截注入了Log4NetHandler。

CustomAttributeMatchingRule没有提供字符形式的构造函数来指定attributeType,在配置文件中获取System.Type类型的TypeConverter失败,导致在转换时无法将字符转换为实际的RuntimeType。不过你可以编写一个继承于CustomAttributeMatchingRule的类型,并通过new关键字隐藏Matches,然后加上一个字符形式的attributeType参数:

 1 public class CustomAttributeMatchingRule2 : CustomAttributeMatchingRule
 2 {
 3   public CustomAttributeMatchingRule2(String attributeType, Boolean inherited)
 4     : base(Type.GetType(attributeType), inherited)
 5   {
 6 
 7   }
 8 
 9   public new Boolean Matches(MethodBase member)
10   {
11     return base.Matches(member);
12   }
13 }

基于CustomAttributeMatchingRule2的配置如下定义:

<unity xmlns=”http://schemas.microsoft.com/practices/2010/unity”>
  <sectionExtension type=”Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration” />

  <assembly name=”mscorlib, 2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089″ />
  <assembly name=”UnityTest6″ />

  <namespace name=”System.ComponentModel” />
  <namespace name=”UnityTest6″ />

  <container>
    <extension type=”Interception” />

    <interception>
      <policy name=”CustomAttributePolicy”>
        <matchingRule name=”CustomAttributeMatchingRule” type=”CustomAttributeMatchingRule2″>
          <constructor>
            <param name=”attributeType” value=”UnityTest6.LogSupportAttribute” />
            <param name=”inherited” value=”true” />
          </constructor>
        </matchingRule>
        <callHandler name=”Log4NetHandler” type=”Log4NetHandler” />
      </policy>
    </interception>

    <register type=”MyObject”>
      <interceptor type=”VirtualMethodInterceptor” />
      <addInterface type=”INotifyPropertyChanged” />
      <interceptionBehavior type=”PolicyInjectionBehavior” />
    </register>
  </container>
</unity>
posted @ 2012-08-10 11:49  junchu25  阅读(701)  评论(0编辑  收藏  举报