上一篇主要是通过继承RealProxy,ProxyAttribute,自定义封装实现AOP。今天主要是介绍Microsoft Enterprise Library 5.0如何实现AOP。
说到使用微软企业库去实现AOP,就不得不说Policy Injection Application Block(PIAB).从字面上来看就是一种注入模块的应用,也就是说将对应的处理操作注入到对应的Method上,使得通过
Method Interception的方式去实现AOP.
Microsoft Enterprise Library提供了
Caching Application Block
Logging Application Block
Exception Handling Application Block
Validation Application Block
Security Application Block
等应用模块,并且可以跟PIAB结合,这此内容其实很多大牛都已写过,这里就不再说了.
一、CBQuoteValidationCallHandler的介绍
所有的类必须引用以下几个NameSpace
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection;
using Microsoft.Practices.Unity.InterceptionExtension;
所有的方法拦截的处理都要继承ICallHandler接口,请看下面代码:
public class CBQuoteValidationCallHandler : ICallHandler
{
public bool IsValidateTotalAmnt { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
if (input == null) throw new ArgumentNullException("input");
if (getNext == null) throw new ArgumentNullException("getNext");
CashBondQuote cbQuote = input.Inputs[0] as CashBondQuote; //约定好所拦截方法第一个参数必须为CashBondQuote
if (cbQuote == null) return getNext()(input, getNext);
if ((cbQuote.TotalFaceValue + cbQuote.AccrdIntrst * cbQuote.TotalFaceValue) != cbQuote.StlmntAmnt)
{
return input.CreateExceptionMethodReturn(new Exception("计算结果不正确!"));
}
if (IsValidateTotalAmnt) //可选项验证
{
}
return getNext()(input, getNext);
}
public int Order
{
get;
set;
}
}
二、另外需要通过Attribute的方式将我们的ICallHandler运用到具体的Method上,请看下面代码:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class CBQuoteValidationCallHandlerAttribute : HandlerAttribute
{
public bool IsValidateTotalAmnt { get; set; } //通过传递IsValidateTotalAmnt参数是否需要应用此可选项验证
public override ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainer container)
{
return new CBQuoteValidationCallHandler() { IsValidateTotalAmnt = this.IsValidateTotalAmnt };
}
}
三、定义需要进行透明代理的类,继承自MarshalByRefObject
public class CashBondBusinessOperation : MarshalByRefObject
{
[CBQuoteValidationCallHandlerAttribute(IsValidateTotalAmnt = false)]
public void BusinessOperation(CashBondQuote cashBondQuote)
{
Console.WriteLine("The CashBond Quote's StlmntAmnt is {0}!", cashBondQuote.StlmntAmnt);
}
public static CashBondQuote CreateCashBondQuote()
{
CashBondQuote cashBondQuote = new CashBondQuote() { TotalFaceValue = 1000000.00m, TotalAccrdIntrst = 10000.003m, StlmntAmnt = 1010000.00m };
return cashBondQuote;
}
}
四、最后是其它的一些辅助类
public class CashBondQuote
{
public CashBondQuote()
{ }
[NotNullValidator(MessageTemplate = "You must specify a value for the 劵面总额.")]
[RegularExpression(@"^\d{1,18}(\.\d{1,2})?$",
ErrorMessage = "劵面总额 must be (18,2) decimal numbers." )]
public decimal? TotalFaceValue
{
get;
set;
}
[NotNullValidator(MessageTemplate = "You must specify a value for the 应计利息总额.")]
[RegularExpression@"^\d{1,18}(\.\d{1,2})?$",
ErrorMessage = "应计利息 must be (18,2) decimal numbers.")]
public decimal? TotalAccrdIntrst
{
get;
set;
}
[NotNullValidator(MessageTemplate = "You must specify a value for the 结算金额.")]
[RegularExpression(@"^\d{1,18}(\.\d{1,2})?$" ,
ErrorMessage = "结算金额 must be (18,2) decimal numbers.")]
public decimal? StlmntAmnt
{
get;
set;
}
}
public class Program
{
static void Main(string[] args)
{
CashBondBusinessOperation cbBo = PolicyInjection.Create<CashBondBusinessOperation>();
CashBondQuote cbQuote = CashBondBusinessOperation.CreateCashBondQuote();
ValidatorFactory valFactory = EnterpriseLibraryContainer.Current.GetInstance<ValidatorFactory>();
Validator<CashBondQuote> productValidator = valFactory.CreateValidator<CashBondQuote>();
// Validate the instance to obtain a collection of validation errors.
ValidationResults results = productValidator.Validate(cbQuote);
if (results.Count > 0)
{
foreach (ValidationResult item in results)
{
Console.WriteLine("Target object: {0}, Member: {1}, Error Message: {2}", item.Target, item.Key, item.Message);
}
}
try
{
cbBo.BusinessOperation(cbQuote);
}
catch (Exception ex)
{
Console.WriteLine("ErrorMessage: {0}", ex.Message);
}
Console.ReadKey();
}
}
运行结果如下图:
大家可以看到CashBondBusinessOperation类中TotalAccrdIntrst = 10000.003m验证出输入的值不正确.
同时验证出计算结果不正确.
那我们改一下TotalAccrdIntrst = 10000.00m
没有问题.
好,这篇文章就写到这.依然欢迎大家提出宝贵意思.