上一篇主要是通过继承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();
      }
   }

 

运行结果如下图:

 

QQ截图20130613145805

 

大家可以看到CashBondBusinessOperation类中TotalAccrdIntrst = 10000.003m验证出输入的值不正确.

同时验证出计算结果不正确.

那我们改一下TotalAccrdIntrst = 10000.00m

QQ截图20130613150809

没有问题.

 

好,这篇文章就写到这.依然欢迎大家提出宝贵意思.

 

 

posted on 2013-06-14 09:29  tzj19810812  阅读(276)  评论(0编辑  收藏  举报