1.
上下文概述
上下文:其实就是一个逻辑上的业务、功能区域。在这个逻辑区域里可以有效的进行管理,算是一种制度的约束,也可以理解为某种范围类的数据共享。
其实在很多应用框架中到处可以看见上下文的概念,包括.NET本身的设计就建立在这种思想上的。实例化的对象默认存在于系统中的默认上下文中,我们可以构建自己的上下文将对象在运行时进行合理的管理。
在ASP.NET框架中比较经典的就是
HttpContext
上下文对象。所有的运行时对象都会逻辑归属到
HttpContext
上下文中来,如:我们可以使用Request
、Response
等对象访问HTTP处理的生命周期数据。
在Remoting中跨
AppDomin访问也是建立在上下文基础上的,请求的消息通过隧道后序列化到达调用发。王清培版权所有,转载请给出署名
在这些强大的应用框架背后总有着让人难以琢磨的设计秘方,诸多的设计原则、设计模式、丰富的实践经验都将是框架稳定运行的基石。Context算是一个比较完美的逻辑范围设计模式。
那么就让我们来领略一下上下文的奥秘吧!
2.
上下文的一般应用
上下文的设计思想绝对的美妙,很多地方一旦进行上下文抽象就能解决很多问题。比如在Remoting中我们可以动态的在上下文中加入很多扩展对上下文中的所有对象进行强制管理,比如:调用某一个方法我们需要进行安全检查,我们可以编写一个满足自己当前项目需求的安全认证插件动态的注入到上下文管理器区域中,在这个地方就体现出上下文的设计优势。
在Web
编程中,由于它有着与
Winfrom
编程很大的差异性,需要将同一组对象同时服务于
N
个客户端进行使用,而在
Winfrom
中基本上都是属于单线程的,当然可以手动的开启多线程并行操作。对于
ASP.NET每当有新的请求处理时,框架会自动开启新的线程去处理当前的调用,然后这个时候就是需要一个相对于之前操作的独立上下文数据环境,而不是在同一个服务器上的所有线程都是共享的。王清培版权所有,转载请给出署名
那么我们就需要将当前的HTTP处理的相关数据纳入到一个逻辑的上下文进行管理和数据共享。
这么多的优势存在,看来我们是有必要尝试一下这中设计模式了。那么就目前系统开发框架而言我们的上下文能用在哪里呢?我想当务之急就是将分层架构中的所有单条线上的对象进行上下文管理。
典型的三层架构:
- using System.Reflection;
- namespace ConsoleApplication1.BLL
- {
- [ContextModule.ContextEveningBound(IsEvening = true)]
- public class BLL_Order : ContextModule.ContextModuleBaseObject<BLL_Order>
- {
- DAL.DAL_Order dal_order = new DAL.DAL_Order();
- [ContextModule.ContextExceptionHandler(OperationSort = 1)]
- public Model.Model_Order InsertOrderSingle(Model.Model_Order ordermodel)
- {
- return ContextModule.ContextAction.PostMethod<DAL.DAL_Order, Model.Model_Order>(
- dal_order, dal_order.GetMethodInfo("InsertOrderSingle"), ordermodel);
- }
- [ContextModule.ContextExceptionHandler(OperationSort = 1)]
- public void SendOrder(Model.Model_Order ordermodel)
- {
- ContextModule.ContextAction.PostMethod<DAL.DAL_Order, object>(
- dal_order, dal_order.GetMethodInfo("SendOrder"), ordermodel);
- }
- }
- }
DAL的执行代码:
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace ConsoleApplication1.DAL
- {
- [ContextModule.ContextEveningBound(IsEvening = true)]
- public class DAL_Order : ContextModule.ContextModuleBaseObject<DAL_Order>
- {
- [ContextModule.ContextLogHandler(OperationSort = 1)]
- [ContextModule.ContextSecurityHanlder(OperationSort = 2)]
- public Model.Model_Order InsertOrderSingle(Model.Model_Order ordermodel)
- {
- return new Model.Model_Order() { OrderGuid = Guid.NewGuid(), OrderTime = DateTime.Now };
- }
- [ContextModule.ContextLogHandler(OperationSort = 1)]
- public void SendOrder(Model.Model_Order ordermodel)
- {
- Console.WriteLine("订单发送成功!");
- }
- }
- }
上述代码是我模拟一个上下文的执行过程。
3.
上下文共享区域
- [ContextModule.ContextExceptionHandler(OperationSort = 1)]
- public void UpdateOrderSingle()
- {
- Model.Model_Order ordermodel = new Model.Model_Order() { OrderGuid = Guid.NewGuid(), OrderTime = DateTime.Now };
- //放入上下文共享对象池
- ContextModule.ContextRuntime.CurrentContextRuntime.SetValue("updateorder", ordermodel);
- ContextModule.ContextAction.PostMethod<DAL.DAL_Order, object>(
- dal_order, dal_order.GetMethodInfo("UpdateOrderSingle"), null);
- }
DAL执行代码:
- [ContextModule.ContextLogHandler(OperationSort = 1)]
- public void UpdateOrderSingle()
- {
- //直接从当前上下文共享区域读取共享值
- Model.Model_Order ordermodel =
- ContextModule.ContextRuntime.CurrentContextRuntime.GetValue("updateorder") as Model.Model_Order;
- }
4.
上下文运行时环境
- /***
- * 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 CurrentContextRuntime { get { return _currentContextRuntime; } }
- /// <summary>
- /// 开始运行时上下文
- /// </summary>
- /// <returns>ContextRuntime</returns>
- public static ContextRuntime BeginContextRuntime()
- {
- //可以通过配置文件配置上下文运行时环境的参数。这里只是实现简单的模拟。
- _currentContextRuntime = new ContextRuntime();
- return _currentContextRuntime;
- }
- }
- }
对于上下文的入口构建:
- //构建上下文运行时环境,上下文的生命周期只存在于当前代码段。
- using (ContextModule.ContextRuntime.BeginContextRuntime())
- {}
通过
Using
的方式我们开始上下文生命周期。
5.
上下文活动对象
- /***
- * author:深度训练
- * blog:http://wangqingpei557.blog.51cto.com/
- * **/
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Data;
- using ConsoleApplication1.BLL;
- using ConsoleApplication1.Model;
- namespace ConsoleApplication1
- {
- public class Program
- {
- public static void Main(string[] args)
- {
- BLL.BLL_Order order = new BLL.BLL_Order();
- using (ContextModule.ContextRuntime.BeginContextRuntime())
- {
- Model.Model_Order ordermodel = new Model_Order() { OrderGuid = Guid.NewGuid(), OrderTime = DateTime.Now };
- Model.Model_Order resultmodel = ContextModule.ContextAction.PostMethod<BLL.BLL_Order, Model.Model_Order>(order, order.GetMethodInfo("InsertOrderSingle"), ordermodel);
- ContextModule.ContextAction.PostMethod<BLL.BLL_Order, object>(order, order.GetMethodInfo("SendOrder"), ordermodel);
- }
- }
- }
- }
6.
上下文在分层架构中的运用
- [ContextModule.ContextEveningBound(IsEvening = true)]
- public class DAL_Order : ContextModule.ContextModuleBaseObject<DAL_Order>
- {
- [ContextModule.ContextLogHandler(OperationSort = 1)]
- [ContextModule.ContextSecurityHanlder(OperationSort = 2)]
- public Model.Model_Order InsertOrderSingle(Model.Model_Order ordermodel)
- {
- //我假设插入成功后,返回带新主键的实体信息。
- return new Model.Model_Order() { OrderGuid = Guid.NewGuid(), OrderTime = DateTime.Now };
- }
在这个类的上面有一个特性ContextEveningBound
,
该是用来表示当前对象属于后期绑定到上下文的对象。同时该类也继承自一个ContextModuleBaseObject<
DAL_Order>泛型类,主要作用是将对象强制的绑定到上下文进行管理。
在方法InsertOrderSingle上面有两个特性,ContextLogHandler是用来记录方法的执行日志,ContextSecurityHanlder是用来在方法执行的过程中强制要求管理员认证。
BLL对象代码:
- [ContextModule.ContextEveningBound(IsEvening = true)]
- public class BLL_Order : ContextModule.ContextModuleBaseObject<BLL_Order>
- {
- DAL.DAL_Order dal_order = new DAL.DAL_Order();
- [ContextModule.ContextExceptionHandler(OperationSort = 1)]
- public Model.Model_Order InsertOrderSingle(Model.Model_Order ordermodel)
- {
- return ContextModule.ContextAction.PostMethod<DAL.DAL_Order, Model.Model_Order>(
- dal_order, dal_order.GetMethodInfo("InsertOrderSingle"), ordermodel);
- }
在BLL对象里面有一个调用DAL对象方法的实例对象,为了演示简单这里没有加入层的依赖注入设计方案,通过直接调用方式。在BLL方法体中有一个专门用来在上下文中调用方法的接口,这是约束目的是为了能让框架切入到方法的执行之前先执行。具体的设计原理我将在下一篇文章中详细讲解。
在方法的上面有一个ContextExceptionHandler特性,目的是安全的调用DAL对象的方法,在有异常的情况下能通过上下文的方式人性化的提示错误信息。这样我们就不需要频繁的编写捕获异常的代码,看起来也不爽,我们要的是代码的整洁、美丽。
UI调用:
- /***
- * author:深度训练
- * blog:http://wangqingpei557.blog.51cto.com/
- * **/
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Data;
- using ConsoleApplication1.BLL;
- using ConsoleApplication1.Model;
- namespace ConsoleApplication1
- {
- public class Program
- {
- public static void Main(string[] args)
- {
- BLL.BLL_Order order = new BLL.BLL_Order();
- //构建上下文运行时环境,上下文的生命周期只存在于当前代码段。
- using (ContextModule.ContextRuntime.BeginContextRuntime())
- {
- Model.Model_Order ordermodel = new Model_Order() { OrderGuid = Guid.NewGuid(), OrderTime = DateTime.Now };
- Model.Model_Order resultmodel =
- ContextModule.ContextAction.PostMethod<BLL.BLL_Order, Model.Model_Order>
- (order, order.GetMethodInfo("InsertOrderSingle"), ordermodel);
- Console.WriteLine("插入成功:" + resultmodel.OrderGuid);
- }
- Console.ReadLine();
- }
- }
- }
执行效果:
我输入YES才能继续执行插入的方法。我们可以通过很简单的实现上下文的管理接口,对方法进行控制。
总结:该篇文章只是介绍上下文的作用、原理、优势。下篇文章:“.NET 面向上下文架构模式(实现)”将详细的介绍上下文框架如何开发。