zoukankan      html  css  js  c++  java
  • 基于Enterprise Library 6 的AOP实现

          最近 Enterprise Library 6 正式版发布了,距离上了版本又有一段时间.首先我们来看下面这张模块图,实线表示强依赖,虚线表示弱依赖(或可选的).
    6.0版本全面支持.net Framework 4.5.

    EntLib6

    相对于前面5.0版本,移除了下面的模块:

    The Caching Application Block
    The Cryptography Application Block
    The Security Application Block

    对于Cache可以考虑试用.net framework基类库中的System.Runtime.Caching类,或是Windows Server AppFabric 缓存特性.

    对于加密这一块,可参考.NET Framework Cryptography Model来代替.

    安全模块可以采用Claims-based来代替,更加信息可参考MSDN.

    参加两个新的模块:

      • Transient Fault Handling Application Block
      • Semantic Logging Application Block

    变化:

    这次有一项改动是那些模块的功能类不再自动从Unity创建了,也就是引导也不依赖Unity容器组件. 这是区别5.0版本的,现在应该删除下面代码:

    AddNewExtension<EnterpriseLibraryCoreExtension>


    例如,使用Logging Application block模块,那需要先使用静态方法注册一下:

                    //From Entlib 6 document:Exception Handling Application Block objects can no longer be created 
                    // automatically from the Unity DI container. 
                    IConfigurationSource configurationSource = ConfigurationSourceFactory.Create();
                    LogWriterFactory logWriterFactory = new LogWriterFactory(configurationSource);
                    Logger.SetLogWriter(logWriterFactory.Create());


    否则可能出现这样的异常:

    The LogWriter has not been set for the Logger static class. Set it invoking the Logger.SetLogWriter method.  


       基于6.0版本实现面向方向的编程AOP, 只需做少许修改即可.以前曾写过一篇文章基于Enterprise Library 4.1版本. 首选,在Nuget上下载相关Enterprise Library 6模块,参考下面的Nuget的XML文件:

    <?xml version="1.0" encoding="utf-8"?>
    <packages>
      <package id="CommonServiceLocator" version="1.0" targetFramework="net45" />
      <package id="EnterpriseLibrary.Common" version="6.0.1304.0" targetFramework="net45" />
      <package id="EnterpriseLibrary.ExceptionHandling" version="6.0.1304.0" targetFramework="net45" />
      <package id="EnterpriseLibrary.ExceptionHandling.Logging" version="6.0.1304.0" targetFramework="net45" />
      <package id="EnterpriseLibrary.Logging" version="6.0.1304.0" targetFramework="net45" />
      <package id="EnterpriseLibrary.PolicyInjection" version="6.0.1304.0" targetFramework="net45" />
      <package id="EnterpriseLibrary.Validation" version="6.0.1304.0" targetFramework="net45" />
      <package id="Unity" version="3.0.1304.0" targetFramework="net45" />
      <package id="Unity.Interception" version="3.0.1304.0" targetFramework="net45" />
      <package id="xunit" version="1.9.1" targetFramework="net45" />
    </packages>


    用一个ServiceFactory来解析Interface,其静态构造方法是这样的,这只是这个类的片断代码:


            static ServiceFactory()
            {
                IUnityContainer container = new UnityContainer();
     
                string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "EntLib.Config");
                var map = new ExeConfigurationFileMap { ExeConfigFilename = path };
                var config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
     
                try
                {
                    var section = (UnityConfigurationSection)config.GetSection("unity");
                    section.Configure(container, "DefContainer");
     
                    //From Entlib 6 document:Exception Handling Application Block objects can no longer be created 
                    // automatically from the Unity DI container. 
                    IConfigurationSource configurationSource = ConfigurationSourceFactory.Create();
                    LogWriterFactory logWriterFactory = new LogWriterFactory(configurationSource);
                    Logger.SetLogWriter(logWriterFactory.Create());
     
                    ExceptionPolicyFactory exceptionPolicyFactory = new ExceptionPolicyFactory(configurationSource);
                    ExceptionPolicy.SetExceptionManager(exceptionPolicyFactory.CreateManager());
                }
                catch (InvalidOperationException ioe)
                {
                    throw;
                }
     
                serviceLocator = new UnityServiceLocator(container);
            }

    上面的代码是从前面Assembly目录,加载一个EntLib.Config的XML配置文件,读取其中的Unity配置节与日志,异常处理的配置节.
    下面以Demo个简单的Interface, 我们在Method加上相应横切的Attribute,分别用作 验证,日志,异常处理:

        [ServiceContract]
        public interface IService1
        {
            [ValidationCallHandler]
            [LogCallHandler(BeforeMessage = "before GetData", AfterMessage = "after GetData",
               IncludeCallStack = true)]
            [ExceptionCallHandler("MyPolicy")]
            [OperationContract]
            string GetData([RangeValidator(1, RangeBoundaryType.Inclusive, 200, RangeBoundaryType.Inclusive)]
                int value);
     
            [OperationContract]
            CompositeType GetDataUsingDataContract(CompositeType composite);
        }


    最后我们用基于xunit的UnitTest来验证一下, AOP拦截对方法参数的验证,之前Method限制了参数值的范围是1-200,第二个方法故意触发这个逻辑.
     

            [Fact]
            public void GetDataWithCuttingConcern()
            {
                //Arrange
                var service = ServiceFactory.GetInstance<WcfService1.IService1>();
                //Act
                string result=service.GetData(100);
     
                //Assert
                Assert.NotNull(result);
            }
     
            [Fact]
            public void GetDataShouldAriseValidationException()
            {
                //Arrange and act
                var service = ServiceFactory.GetInstance<WcfService1.IService1>();
     
                //Assert
                Assert.Throws<ArgumentValidationException>(()=>service.GetData(300));
            }


    鉴于篇幅有限,基于XML的Enterprise Library配置文件不在这儿就贴了,请参考以前的文章,使用时可用EntLib 6 配置控制台更新一下配置文件.


    希望对您软件开发有帮助.
    你可能感兴趣的文章:

    使用Unity2.0的Interceptor实现简单AOP
    使用EnterpriseLibrary的PIAB与Unity搭建简单AOP框架


    作者:Petter Liu
    出处:http://www.cnblogs.com/wintersun/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    该文章也同时发布在我的独立博客中-Petter Liu Blog

  • 相关阅读:
    mysql 主键、复合主键等
    win7 增加edit with vim右键菜单
    设计模式学习1:简单工厂模式实现加减乘除等运算
    C#练习笔记3:分部类分部方法,索引结合异常的使用
    C#练习笔记4:枚举和数组练习
    C#练习笔记2:dll的编写与引用
    C#练习笔记1:自定义的类型转换和操作符的重载
    学习杂记1:c#,顺序泛型栈,泛型委托,Lambda,拓展方法
    数据结构学习日记3:顺序栈的实现(两种不同的方法)
    Unity中字幕的一个简单实现方式小结
  • 原文地址:https://www.cnblogs.com/wintersun/p/3071246.html
Copyright © 2011-2022 走看看