.NET面向上下文、AOP架构模式(概述)

1. 上下文概述

上下文:其实就是一个逻辑上的业务、功能区域。在这个逻辑区域里可以有效的进行管理,算是一种制度的约束,也可以理解为某种范围类的数据共享。

其实在很多应用框架中到处可以看见上下文的概念,包括.NET本身的设计就建立在这种思想上的。实例化的对象默认存在于系统中的默认上下文中,我们可以构建自己的上下文将对象在运行时进行合理的管理。

在ASP.NET框架中比较经典的就是HttpContext上下文对象。所有的运行时对象都会逻辑归属到HttpContext上下文中来,如:我们可以使用Request、Response等对象访问HTTP处理的生命周期数据。

在Remoting中跨AppDomin访问也是建立在上下文基础上的,请求的消息通过隧道后序列化到达调用发。王清培版权所有,转载请给出署名

在这些强大的应用框架背后总有着让人难以琢磨的设计秘方,诸多的设计原则、设计模式、丰富的实践经验都将是框架稳定运行的基石。Context算是一个比较完美的逻辑范围设计模式。[王清培版权所有,转载请给出署名]

那么就让我们来领略一下上下文的奥秘吧!

2. 上下文的一般应用

上下文的设计思想绝对的美妙,很多地方一旦进行上下文抽象就能解决很多问题。比如在Remoting中我们可以动态的在上下文中加入很多扩展对上下文中的所有对象进行强制管理,比如:调用某一个方法我们需要进行安全检查,我们可以编写一个满足自己当前项目需求的安全认证插件动态的注入到上下文管理器区域中,在这个地方就体现出上下文的设计优势。

在Web编程中,由于它有着与Winfrom编程很大的差异性,需要将同一组对象同时服务于N个客户端进行使用,而在Winfrom中基本上都是属于单线程的,当然可以手动的开启多线程并行操作。对于ASP.NET每当有新的请求处理时,框架会自动开启新的线程去处理当前的调用,然后这个时候就是需要一个相对于之前操作的独立上下文数据环境,而不是在同一个服务器上的所有线程都是共享的。王清培版权所有,转载请给出署名

那么我们就需要将当前的HTTP处理的相关数据纳入到一个逻辑的上下文进行管理和数据共享。

这么多的优势存在,看来我们是有必要尝试一下这中设计模式了。那么就目前系统开发框架而言我们的上下文能用在哪里呢?我想当务之急就是将分层架构中的所有单条线上的对象进行上下文管理。[王清培版权所有,转载请给出署名]

典型的三层架构:

在一般的三层架构开发过程中我们的调用关系基本都是这样的,利用上下文设计模式我们可以将本来鼓励的对象进行合理的管理。上图中User对象线将是属于User上下文的,Order对象线将是属于Order上下文的。大家互不干扰,可以在这个逻辑上下文中共享数据、设置调用安全策略、设计日志记录方式、甚至可以计算每个方法的性能。

BLL的调用代码:

View Code

 1 /***
 2  * author:深度训练
 3  * blog:http://wangqingpei557.blog.51cto.com/
 4  * **/
 5 using System;
 6 using System.Collections.Generic;
 7 using System.Text;
 8 using System.Reflection;
 9
10 namespace ConsoleApplication1.BLL
11 {
12     [ContextModule.ContextEveningBound(IsEvening = true)]
13     public class BLL_Order : ContextModule.ContextModuleBaseObject<BLL_Order>
14     {
15         DAL.DAL_Order dal_order = new DAL.DAL_Order();
16
17         [ContextModule.ContextExceptionHandler(OperationSort = 1)]
18         public Model.Model_Order InsertOrderSingle(Model.Model_Order ordermodel)
19         {
20             return ContextModule.ContextAction.PostMethod<DAL.DAL_Order, Model.Model_Order>(
21                 dal_order, dal_order.GetMethodInfo("InsertOrderSingle"), ordermodel);
22         }
23         [ContextModule.ContextExceptionHandler(OperationSort = 1)]
24         public void SendOrder(Model.Model_Order ordermodel)
25         {
26             ContextModule.ContextAction.PostMethod<DAL.DAL_Order, object>(
27                dal_order, dal_order.GetMethodInfo("SendOrder"), ordermodel);
28         }
29     }
30 }

DAL的执行代码:

View Code

 1 /***
 2  * author:深度训练
 3  * blog:http://wangqingpei557.blog.51cto.com/
 4  * **/
 5 using System;
 6 using System.Collections.Generic;
 7 using System.Text;
 8
 9 namespace ConsoleApplication1.DAL
10 {
11     [ContextModule.ContextEveningBound(IsEvening = true)]
12     public class DAL_Order : ContextModule.ContextModuleBaseObject<DAL_Order>
13     {
14         [ContextModule.ContextLogHandler(OperationSort = 1)]
15         [ContextModule.ContextSecurityHanlder(OperationSort = 2)]
16         public Model.Model_Order InsertOrderSingle(Model.Model_Order ordermodel)
17         {
18             return new Model.Model_Order() { OrderGuid = Guid.NewGuid(), OrderTime = DateTime.Now };
19         }
20         [ContextModule.ContextLogHandler(OperationSort = 1)]
21         public void SendOrder(Model.Model_Order ordermodel)
22         {
23             Console.WriteLine("订单发送成功!");
24         }
25     }
26 }

上述代码是我模拟一个上下文的执行过程。

3. 上下文共享区域

在每个独立的上下文环境中应该有一片共享的数据存储区域,以备多个上下文对象访问。这种方便性多半存在于项目比较紧张的修改需求的时候或者加新业务的时候扩展方法用的。BLL调用代码:

View Code

1 [ContextModule.ContextExceptionHandler(OperationSort = 1)]
2         public void UpdateOrderSingle()
3         {
4             Model.Model_Order ordermodel = new Model.Model_Order() { OrderGuid = Guid.NewGuid(), OrderTime = DateTime.Now };
5             //放入上下文共享对象池
6             ContextModule.ContextRuntime.CurrentContextRuntime.SetValue("updateorder", ordermodel);
7             ContextModule.ContextAction.PostMethod<DAL.DAL_Order, object>(
8                 dal_order, dal_order.GetMethodInfo("UpdateOrderSingle"), null);
9         }

DAL执行代码:

View Code

1  [ContextModule.ContextLogHandler(OperationSort = 1)]
2         public void UpdateOrderSingle()
3         {
4             Model.Model_Order ordermodel =
5                 ContextModule.ContextRuntime.CurrentContextRuntime.GetValue("updateorder") as Model.Model_Order;
6         }

4. 上下文运行时环境

对于上下文运行时环境的构建需要考虑到运行时是共享的上下文对象。对于纳入上下文管理的所有对象都需要共享或者说是受控于上下文运行时。

上下文构建:

View Code

 1 /***
 2  * author:深度训练
 3  * blog:http://wangqingpei557.blog.51cto.com/
 4  * **/
 5 using System;
 6 using System.Collections.Generic;
 7 using System.Text;
 8
 9 namespace ContextModule
10 {
11     /// <summary>
12     /// 上下文运行时环境。
13     /// 上下文逻辑运行时环境,环境中的功能都是可以通过附加进来的。
14     /// </summary>
15     public class ContextRuntime : IDisposable
16     {
17         #region IDisposable成员
18         void IDisposable.Dispose()
19         {
20             _currentContextRuntime = null;
21         }
22         #endregion
23
24         protected ContextRuntime() { }
25         private DateTime _initTime = DateTime.Now;
26         /// <summary>
27         /// 获取运行时创建上下文的时间
28         /// </summary>
29         public virtual DateTime InitTime { get { return _initTime; } }
30         private Dictionary<object, object> _runTimeResource = new Dictionary<object, object>();
31         private ContextFilterHandlerMap _filterMap = new ContextFilterHandlerMap();
32         /// <summary>
33         /// 获取上下文中的方法、类过滤器映射表
34         /// </summary>
35         public ContextFilterHandlerMap FilterMap { get { return _filterMap; } }
36         private Guid _initPrimaryKey = Guid.NewGuid();
37         /// <summary>
38         /// 获取运行时创建上下文的唯一标识
39         /// </summary>
40         public virtual Guid InitPrimaryKey { get { return _initPrimaryKey; } }
41         /// <summary>
42         /// 获取上下文共享区域中的数据
43         /// </summary>
44         /// <param name="key">数据Key</param>
45         /// <returns>object数据对象</returns>
46         public virtual object GetValue(object key)
47         {
48             return _runTimeResource[key];
49         }
50         /// <summary>
51         /// 设置上下文共享区域中的数据
52         /// </summary>
53         /// <param name="key">数据Key</param>
54         /// <param name="value">要设置的数据对象</param>
55         public virtual void SetValue(object key, object value)
56         {
57             _runTimeResource[key] = value;
58         }
59
60         [ThreadStatic]
61         private static ContextRuntime _currentContextRuntime;
62         /// <summary>
63         /// 获取当前上下文运行时对象.
64         /// </summary>
65         public static ContextRuntime CurrentContextRuntime { get { return _currentContextRuntime; } }
66         /// <summary>
67         /// 开始运行时上下文
68         /// </summary>
69         /// <returns>ContextRuntime</returns>
70         public static ContextRuntime BeginContextRuntime()
71         {
72             //可以通过配置文件配置上下文运行时环境的参数。这里只是实现简单的模拟。
73             _currentContextRuntime = new ContextRuntime();
74             return _currentContextRuntime;
75         }
76     }
77 }

对于上下文的入口构建:

View Code

1             using (ContextModule.ContextRuntime.BeginContextRuntime())
2             {
3
4             }

通过Using的方式我们开始上下文生命周期。

5. 上下文活动对象

上下文对象的绑定需要延后,不能在对象的构建时就创建上下文。

使用后期绑定动态的切入到执行的上下文中。

调用代码,上下文入口:

View Code

 1 /***
 2  * author:深度训练
 3  * blog:http://wangqingpei557.blog.51cto.com/
 4  * **/
 5 using System;
 6 using System.Collections.Generic;
 7 using System.Text;
 8 using System.Data;
 9 using ConsoleApplication1.BLL;
10 using ConsoleApplication1.Model;
11
12 namespace ConsoleApplication1
13 {
14     public class Program
15     {
16         public static void Main(string[] args)
17         {
18             BLL.BLL_Order order = new BLL.BLL_Order();
19             using (ContextModule.ContextRuntime.BeginContextRuntime())
20             {
21                 Model.Model_Order ordermodel = new Model_Order() { OrderGuid = Guid.NewGuid(), OrderTime = DateTime.Now };
22                 Model.Model_Order resultmodel = ContextModule.ContextAction.PostMethod<BLL.BLL_Order, Model.Model_Order>(order, order.GetMethodInfo("InsertOrderSingle"), ordermodel);
23                 ContextModule.ContextAction.PostMethod<BLL.BLL_Order, object>(order, order.GetMethodInfo("SendOrder"), ordermodel);
24             }
25
26         }
27     }
28 }

6. 上下文在分层架构中的运用

有了上下文的核心原型之后我们可以扩展到分层架构中来,对于分层架构的使用其实很有必要,一般的大型业务系统都是混合的使用模式,可能有C/S、B/S、Mobile终端等等。

对于加入Service层之后BLL、DAL将位于服务之后,对于来自客户端的调用需要经过一些列的身份验证及权限授予。有了WCF之后面向SOA的架构开发变的相对容易点,对安全、性能、负载等等都很完美,所以大部分的情况下我们很少需要控制BLL、DAL的执行运行。

那么没有使用WCF构建分布式的系统时或者是没有分布式的需求就是直接的调用,如WEB的一般开发,从UI到BLL到DAL。或者是普通的Winfrom的项目、控制台项目属于内网的使用,可能就需要控制到代码的执行。

下面我通过演示一个具体的实例来看看到底效果如何。

我以控制台的程序作为演示项目类型,也使用简单的三层架构。

这个再简单不过了吧,为了演示越简单越好,关键是突出重点。

需求:

在DAL对象里面加入一个插入Order实体对象的方法:

View Code

 1 /***
 2  * author:深度训练
 3  * blog:http://wangqingpei557.blog.51cto.com/
 4  * **/
 5 using System;
 6 using System.Collections.Generic;
 7 using System.Text;
 8
 9 namespace ConsoleApplication1.DAL
10 {
11     [ContextModule.ContextEveningBound(IsEvening = true)]
12     public class DAL_Order : ContextModule.ContextModuleBaseObject<DAL_Order>
13     {
14         [ContextModule.ContextLogHandler(OperationSort = 1)]
15         [ContextModule.ContextSecurityHanlder(OperationSort = 2)]
16         public Model.Model_Order InsertOrderSingle(Model.Model_Order ordermodel)
17         {
18             return new Model.Model_Order() { OrderGuid = Guid.NewGuid(), OrderTime = DateTime.Now };
19         }
20     }
21 }

在这个类的上面有一个特性ContextEveningBound,该是用来表示当前对象属于后期绑定到上下文的对象。同时该类也继承自一个ContextModuleBaseObject<DAL_Order>泛型类,主要作用是将对象强制的绑定到上下文进行管理。

在方法InsertOrderSingle上面有两个特性,ContextLogHandler是用来记录方法的执行日志,ContextSecurityHanlder是用来在方法执行的过程中强制要求管理员认证。

BLL对象代码:

View Code

 1 /***
 2  * author:深度训练
 3  * blog:http://wangqingpei557.blog.51cto.com/
 4  * **/
 5 using System;
 6 using System.Collections.Generic;
 7 using System.Text;
 8 using System.Reflection;
 9
10 namespace ConsoleApplication1.BLL
11 {
12     [ContextModule.ContextEveningBound(IsEvening = true)]
13     public class BLL_Order : ContextModule.ContextModuleBaseObject<BLL_Order>
14     {
15         DAL.DAL_Order dal_order = new DAL.DAL_Order();
16
17         [ContextModule.ContextExceptionHandler(OperationSort = 1)]
18         public Model.Model_Order InsertOrderSingle(Model.Model_Order ordermodel)
19         {
20             return ContextModule.ContextAction.PostMethod<DAL.DAL_Order, Model.Model_Order>(
21                 dal_order, dal_order.GetMethodInfo("InsertOrderSingle"), ordermodel);
22         }
23     }
24 }

在BLL对象里面有一个调用DAL对象方法的实例对象,为了演示简单这里没有加入层的依赖注入设计方案,通过直接调用方式。在BLL方法体中有一个专门用来在上下文中调用方法的接口,这是约束目的是为了能让框架切入到方法的执行之前先执行。具体的设计原理我将在下一篇文章中详细讲解。

在方法的上面有一个ContextExceptionHandler特性,目的是安全的调用DAL对象的方法,在有异常的情况下能通过上下文的方式人性化的提示错误信息。这样我们就不需要频繁的编写捕获异常的代码,看起来也不爽,我们要的是代码的整洁、美丽。

UI调用:

View Code

 1 /***
 2  * author:深度训练
 3  * blog:http://wangqingpei557.blog.51cto.com/
 4  * **/
 5 using System;
 6 using System.Collections.Generic;
 7 using System.Text;
 8 using System.Data;
 9 using ConsoleApplication1.BLL;
10 using ConsoleApplication1.Model;
11
12 namespace ConsoleApplication1
13 {
14     public class Program
15     {
16         public static void Main(string[] args)
17         {
18             BLL.BLL_Order order = new BLL.BLL_Order();
19             //开启上下文
20             using (ContextModule.ContextRuntime.BeginContextRuntime())
21             {
22                 Model.Model_Order ordermodel = new Model_Order() { OrderGuid = Guid.NewGuid(), OrderTime = DateTime.Now };
23
24                 Model.Model_Order resultmodel =
25                     ContextModule.ContextAction.PostMethod<BLL.BLL_Order, Model.Model_Order>(
26                     order, order.GetMethodInfo("InsertOrderSingle"), ordermodel);
27             }
28
29         }
30     }
31 }

执行效果:

会先执行日志的记录,然后要求我们输入用户凭证才能继续执行下面的方法。

我输入YES才能继续执行插入的方法。我们可以通过很简单的实现上下文的管理接口,对方法进行控制。

总结:该篇文章只是介绍上下文的作用、原理、优势。下篇文章:“.NET 面向上下文架构模式(实现)”将详细的介绍上下文框架如何开发。[王清培版权所有,转载请给出署名]

时间: 2024-09-25 15:13:52

.NET面向上下文、AOP架构模式(概述)的相关文章

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

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

业务层架构模式

一:业务层架构模式概述 在三层架构中,业务层负责所有业务相关的工作,包括根据输入数据或已有数据进行计算,对从表示层输入的数据进行验证,以及根据从表示层接收的命令来确定应该调用哪些数据访问逻辑.对于应用系统来说,业务层主要维护业务逻辑,是系统的核心部分.因此,在应用系统开发时,业务层的开发是最为关键的. 业务层的架构模式有多种,最著名的就是以下两种 : 事务脚本模型(面向过程的设计) 领域模型(面向对象的设计)   二:事务脚本模型 事务脚本(Transaction Script)架构模型是按照传

面向移动互联网的需求管理与应用架构模式研究

随着3G/4G移动通信技术和云计算.大数据等信息技术的不断发展和成熟,逐渐形成了"移动终端+无线通信网络+平台+应用"的价值承载体系结构,人们也逐渐习惯了借助移动终端完成互联网服务的消费,标志着人类社会已经步入移动互联网时代. 针对移动互联网时代对于服务提供商的要求,电信运营商需要在需求管理和应用开发模式方面进行创新.电信运营商传统的需求管理模式往往是业务部门在市场经营中形成对于业务支撑系统的需求,然后有软件开发商进行需求调研并开发实施.这种需求管理和应用开发模式最大的问题就是开发周期

软件体系架构模式在J2EE中的应用

本文介绍了软件体系架构产生的背景和架构模式的基本理论.重点介绍管道与过滤器体系架构模式的结构,实现,优缺点等,然后以J2EE的Servlet Filter为例进行剖析它是怎样应用该架构模式的,最后简单阐述了在其它J2ee应用中(Jboss和Axis)的实践. 软件体系架构 1.软件体系架构产生背景 在经历60年代的软件危机之后,使人们开始重视软件工程的研究.来自不同应用领域的软件专家总结了大量的有价值的知识. 当初,人们把软件设计的重点放在数据结构和算法的选择上,如Knuth提出了数据结构+算法

Java的Spring框架下的AOP编程模式示例_java

Spring框架的关键组件是面向方面编程(AOP)框架.面向方面的编程不仅打破程序逻辑分成不同的部分称为所谓的担忧.跨越多个点的应用程序的功能被称为横切关注点和这些横切关注点是从应用程序的业务逻辑概念上区分开来.还有像日志记录,审计,声明性事务,安全性和高速缓存等方面的各种常见的好例子 模块化的OOP中的关键单元是类,而在AOP中模块化的单元则是切面.依赖注入可以帮助你从对方解耦应用程序对象和AOP可以帮助你从他们影响的对象分离横切关注点. AOP是一样的编程语言如Perl,.NET,Java和

iOS 开发中的 Flux 架构模式

本文讲的是iOS 开发中的 Flux 架构模式, 在半年前,我开始在 PlanGrid iOS 应用程序中采用 Flux 架构(开发).这篇文章将会讨论我们从传统的 MVC 转换到Flux的动机,同时分享我们目前积累到的经验. 我尝试通过讨论代码来描述我们大部分的 Flux 实现, 它用于我们今天的产品中. 如果你只对综合结果感兴趣, 请跳过这篇文章的中间部分. 为什么从 MVC 转移 为了引入我们的决定, 我想要先谈一谈 PlanGrid 这个应用遇到的一些挑战.一些问题仅针对企业级应用程序,

微服务:真正的架构模式

本文讲的是微服务:真正的架构模式[编者的话]本文来自Medium,通过比较CRUD app和数据流app两种应用类型的微服务化探索来向听众介绍微服务. 简介 微服务的神秘和背后的知识令我着迷.微服务作为概念,它属于现代最有趣的架构之一.微服务应用广泛,涉及不同的使用场景.但也有很多地方模糊不清,难以定论. 人们在讨论微服务时,我会努力理解他们的真实意图.尽管在上一次演讲中我分享了对微服务的认识,但我很清楚其它公司和我们使用的架构是不一样的.最近我询问了一位同行,了解到他们部署微服务的方式(和我)

设计模式、企业应用架构模式和架构模式学习总结

设计模式: 简单工厂模式 工厂方法模式 抽象工厂方法模式 单例模式 外观模式 生成器模式 原形模式 中介者模式 代理模式 观察者模式 命令模式 迭代器模式 组合模式 模版方法模式 策略模式 状态模式 备忘录模式 享元模式 解释器模式 装饰器模式 职责链模式 桥接模式 访问者模式 企业应用架构模式 事务脚本 大家都懂的写法 领域模型 DDD的建模方法:领域对象.value对象 Unit of Work Entity Framework已经集成这功能了 Lazy Load 同上 查询对象 针对Spe

MVC架构模式与利用JAVABEAN分页

众所周知MVC不是设计模式,是一个比设计模式更大一点的模式,称作设计模式不合理,MVC模式应该叫架构模式,MVC里面用了许多小的模式,例如策略模式,组合模式,聚集模式,可以用到的模式有十几种之多,而设计模式里也就27种,MVC很重要,现在流行的STRUTS框架也是类似的实现,建议大家有时间可以研究下STRUTS,现在很多公司都开始使用这个框架来做大型的企业系统开发,STRUTS是APACHE的一个开源项目,所有资料都可以从APACHE网站得到.当然目前国内也有翻译了一些STRUTS文章,不过大都