微软企业库5.0 学习之路——第九步、使用PolicyInjection模块进行AOP—PART2——自定义Matching Rule
这段时间公司有新项目需要开发,所以这个企业库学习之路有点耽误了,今天继续接着上一篇文章,在上一篇文章中,我介绍了企业库的自带Matching Rule(匹配规则)的基本信息及使用方法,但是在PolicyInjection模块中的Matching Rule(匹配规则)还有2个规则没有介绍,分别是:
1、Custom Attribute Matching Rule——自定义特性匹配规则
2、Custom Matching Rule——自定义匹配规则
今天就主要对这2个匹配规则进行介绍,及有关这2个匹配规则的一些应用例子。
一、Custom Attribute Matching Rule——自定义特性匹配规则
这个匹配规则有点类似于Tag Attribute Matching Rule,只不过Tag Attribute Matching Rule已经定死了特性类——TagAttribute,具体匹配需要靠TagAttribute特性类的tag字符串来标识具体的策略名,使用起来不怎么方便,而且使用字符串来标识,可能会写错,不过企业库同样为我们预留了扩展接口,就是这个自定义特性匹配规则——Custom Attribute Matching Rule。
这个匹配规则使用起来很简单,只需自己定义个特性类,然后在企业库配置工具中进行配置既可。
这个匹配规则接收2个参数:Attribute Type Name和Search Inheritance Chain
1、Attribute Type Name,这个意思很明确了,就是特性类的名称,只需点击旁边的选择按钮即可选择到自己定义的特性类。
2、Search Inheritance Chain,这个是表示是否要查询继承关系,默认为false,表示不查询,看下面的代码就可以理解了:
我首先定义了一个自定义的特性类:
[AttributeUsage(AttributeTargets.Method)] public class MyCustomAttribute:System.Attribute { }
然后在应用到代码中:
public abstract class CustomAttrTest : MarshalByRefObject { [MyCustom] public abstract void CwInfo(string aa); } public class ChildCustomerAttrTest : CustomAttrTest { public override void CwInfo(string aa) { Console.WriteLine(aa); } }
可以看到我将MyCustomAttribute应用到了抽象类CustomAttrTest中的抽象方法CwInfo上,然后由子类 ChildCustomerAttrTest来实现,如果将Search Inheritance Chain设置为false,则在方法调用的过程中将不会被拦截,因为MyCustomAttribute是应用在抽象类中,而不是应用在实现类中,所以 如果想依靠抽象类来定义拦截,则需要将Search Inheritance Chain设置为true。
具体配置图如下:
注:由于PolicyInjection模块的一个BUG问题,在通过PolicyInjection创建对象的时候,如果创建的对象需要指向一个抽象类将会报错,代码如下:
1CustomAttrTest customAttr = PolicyInjection.Create<ChildCustomerAttrTest, CustomAttrTest>();
具体的问题,可以参考Artech写的这篇文章:这是EnterLib PIAB的BUG吗?,里面介绍了这个问题的产生原因及解决办法。
通过Custom Attribute Matching Rule我们可以根据我们自己的具体需求自由建立特性类,比如:异常、权限、日志等等,通过自己来建立特性类,这样我们可以很好的分隔各个功能,在具体的时候过程中我们可以自由组合所需要的功能,如下代码:
我首先定义几个需要使用的特性类:
[AttributeUsage(AttributeTargets.Method)] public class ExceptionAttribute : System.Attribute { } [AttributeUsage(AttributeTargets.Method)] public class LoggingAttribute : System.Attribute { } [AttributeUsage(AttributeTargets.Method)] public class SecurityAttribute : System.Attribute { } public class MyCommonAttribute : System.Attribute { }
然后为每个特性类关联不同处理操作:
[MyCustom] [Logging] [Exception] public void Delete(int id) { }
二、Custom Matching Rule——自定义匹配规则
如果企业库内置的那么多匹配规则都无法达到你想要的话,你可以尝试着自己编写匹配规则,当然企业库也预留了这个接口,就是Custom Matching Rule。如果要自己实现一个Custom Matching Rule,主要分为2步:
1、建立一个类继承自接口IMatchingRule(这个接口是属于 Microsoft.Practices.Unity.InterceptionExtension,需要引用Unity.dll),并实现方法bool Matches(System.Reflection.MethodBase member)。
2、为类加上特性[ConfigurationElementType(typeof(CustomMatchingRuleData))](需要引用命名空间Microsoft.Practices.EnterpriseLibrary.Common.Configuration 和Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration),标识 其继承自CustomMatchingRuleData,可以被企业库配置工具识别到。
代码如下:
using Microsoft.Practices.Unity.InterceptionExtension; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration; using Microsoft.Practices.EnterpriseLibrary.PolicyInjection.Configuration; namespace AOPAssembly { [ConfigurationElementType(typeof(CustomMatchingRuleData))] public class MyCustomMatchRule : IMatchingRule { NameValueCollection attributes = null; public MyCustomMatchRule(NameValueCollection attributes) { this.attributes = attributes; } public bool Matches(System.Reflection.MethodBase member) { bool result = false; if (this.attributes["matchname"] != null) { if (this.attributes["matchname"] == member.Name) { result = true; } } return result; } } }
配置图如下:
这样就可以在Matches方法中编写匹配方法,我这边写了个简单匹配,对根据方法名进行匹配。
这个匹配是通过配置工具中配置的方法名进行匹配,如果配置的方法名和所调用的方法名相同则返回匹配成功。这 里需要注意的是,如果想要在自己实现的自定义匹配类获取到配置工具中所定义的配置,需要定义一个构造函数,接收类型为 NameValueCollection的参数,我这边就通过在类中定义一个attributes参数来接收配置工具中所配置的参数,然后在 Matches方法中进行处理。