开发者论坛

 找回密码
 注册 (请使用非IE浏览器)
查看: 6237|回复: 1

基于Enterprise Library 6 的AOP实现

[复制链接]

0

精华

748

贡献

295

赞扬

正版授权组

Rank: 14Rank: 14Rank: 14Rank: 14

帖子
61
软币
2967
在线时间
238 小时
注册时间
2013-6-9
发表于 2013-7-3 19:48:53 | 显示全部楼层 |阅读模式
      最近 Enterprise Library 6 正式版发布了,距离上了版本又有一段时间.首先我们来看下面这张模块图,实线表示强依赖,虚线表示弱依赖(或可选的).
6.0版本全面支持.net Framework 4.5.

相对于前面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


回复

使用道具 举报

0

精华

158

贡献

2488

赞扬

帖子
709
软币
9818
在线时间
1143 小时
注册时间
2013-8-1
发表于 2015-7-3 11:03:29 | 显示全部楼层
Enterprise Library 是否已经死了,最新的是2013.04发布的,2年多没有更新了。
回复

使用道具 举报

Archiver|手机版|小黑屋|开发者网 ( 苏ICP备08004430号-2 )
版权所有:南京韵文教育信息咨询有限公司

GMT+8, 2024-12-22 09:52

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表