当前位置:编程学习 > asp >>

.NET面向上下文、AOP架构模式(实现)

1.上下文Context、面向切面编程AOP模型分析
在本人的“.NET面向上下文、AOP架构模式(概述)”一文中,我们大概了解了上下文如何辅助对象在运行时的管理。在很多时候我们急需在运行时能把对象控制在一定的逻辑范围内,在必要的时候能让他们体现出集中化的概念,如人群、车辆、动物等等。而Context与AOP有着密切的联系,Context表示逻辑抽象的范围而AOP描述了在这个逻辑范围内如何进行控制。其实这两者都是设计模式外的设计模式,与具体的技术实现无关。[王清培版权所有,转载请给出署名]
那么Context与AOP两者在逻辑上是一个怎样的概念呢?似乎只有图才能最贴切的表达人的理解思路。下图展现Context与AOP紧密合作的概念模型。
Context图:1

对象在运行时被上下文管理,在上下文中可以很方便的获取到所有的受管理的对象,这为后面的AOP做了铺垫。只有Context启动后AOP管理器的爪子才能伸进对象的运行时内部与AOP的连接点建立起通讯关系,才能真正的使对象能面向切面成功。
在模型图中,Context中心负责对所有Object进行管理,而Object体现出多面性属性、多面性行为都将包括多面性的特点,通过与AOP管理器进行连接将控制对象的运行时行为。
AOP图:2

通过合理的约定对象的AOP抽象接口,尽可能的最大化将控制权移动到客户所实现的“面”中去。比如对某类方法的调用,可能需要尽可能的控制方法的所有执行权。所以对具体的抽象定义有很大的难度。
在上图中,我们通过AOP核心管理器与对象的“面”连接上,根据具体的“面”类型进行动态调用,比如属性,可能需要在运行时根据业务环节进行呈现、动态绑定等等,都可以通过AOP去实现。对于方法,可能在面向SOA的架构中需要记录下当前客户端的调用信息,还有一些独特的业务认证等等。不同的“面”需要进行逻辑抽象,这也符合面向对象的设计原则。很多时候我们需要先“约定”而不是尽可能的提供扩展的机制,扩展点越多系统的复杂程度就越大,相对也就难以控制。
2.上下文的实现
对上下文、AOP模型我们大致分析了一下,通过模型图也很形象的体现出上下文、AOP的主要的工作原理。下面我们来通过具体的分析来搭建物理的代码模型。
面向对象是对抽象的逻辑模型进行物理性的建模,能否真正的体现出模型,需要我们细心的分析才行。
2.1上下文模型实现
我们对上下文模型进行抽象实现为代码模型。那么我们需要一个逻辑上代表上下文的对象,在这里我将它命名为ContextRuntime,上下文的生命周期控制在Using()语句的代码段中,那么ContextRuntime需要实现Idisposable接口,让Using()语句能起作用。
using (ContextModule.ContextRuntime.BeginContextRuntime())
{   //上下文的生命周期
}
为什么要这样设计上下文的生命周期呢,这样设计是最为灵活的。在诸如很多微软的内部上下文生命周期的入口也是这样设计的,最经典的就是System.Transaction事务处理。
当Using()代码段结束后,我们需要释放当前上下文实例,所以我们需要完成IDisposable接口的实现。
void IDisposable.Dispose()
{
_currentContextRuntime = null;
}
_ currentContextRuntime表示上下文对象实例的全局私有对象。
由于多线程应用框架的入口点不是我们所能控制的,所以在使用上下文模式的时候需要使用线程本地存储解决线程不安全访问的问题。
 [ThreadStatic]
private static ContextRuntime _currentContextRuntime;
我们看一下全部的ContextRuntime对象代码:
[csharp] 
/***
 * author:深度训练
 * blog:http://wangqingpei557.blog.51cto.com/
 * **/ 
using System; 
using System.Collections.Generic; 
using System.Text; 
 
namespace ContextModule 

    /// <summary> 
    /// 上下文运行时环境。 
    /// 上下文逻辑运行时环境,环境中的功能都是可以通过附加进来的。 
    /// </summary> 
    public class ContextRuntime : IDisposable 
    { 
        #region IDisposable成员 
        void IDisposable.Dispose() 
        { 
            _currentContextRuntime = null; 
        } 
        #endregion 
 
        protected ContextRuntime() { } 
        private DateTime _initTime = DateTime.Now; 
        /// <summary> 
        /// 获取运行时创建上下文的时间 
        /// </summary> 
        public virtual DateTime InitTime { get { return _initTime; } } 
        private Dictionary<object, object> _runTimeResource = new Dictionary<object, object>(); 
        private ContextFilterHandlerMap _filterMap = new ContextFilterHandlerMap(); 
        /// <summary> 
        /// 获取上下文中的方法、类过滤器映射表 
        /// </summary> 
        public ContextFilterHandlerMap FilterMap { get { return _filterMap; } } 
        private Guid _initPrimaryKey = Guid.NewGuid(); 
        /// <summary> 
        /// 获取运行时创建上下文的唯一标识 
        /// </summary> 
        public virtual Guid InitPrimaryKey { get { return _initPrimaryKey; } } 
        /// <summary> 
        /// 获取上下文共享区域中的数据 
        /// </summary> 
        /// <param name="key">数据Key</param> 
        /// <returns>object数据对象</returns> 
        public virtual object GetValue(object key) 
        { 
            return _runTimeResource[key]; 
        } 
        /// <summary> 
        /// 设置上下文共享区域中的数据 
        /// </summary> 
        /// <param name="key">数据Key</param> 
        /// <param name="value">要设置的数据对象</param> 
        public virtual void SetValue(object key, object value) 
        { 
            _runTimeResource[key] = value; 
        } 
 
        [ThreadStatic] 
        private static ContextRuntime _currentContextRuntime; 
        /// <summary> 
        /// 获取当前上下文运行时对象. 
        /// </summary> 
        public static ContextRuntime

补充:Web开发 , ASP.Net ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,