在一般的三层架构开发过程中我们的调用关系基本都是这样的,利用上下文设计模式我们可以将本来鼓励的对象进行合理的管理。上图中User对象线将是属于User上下文的,Order对象线将是属于Order上下文的。大家互不干扰,可以在这个逻辑上下文中共享数据、设置调用安全策略、设计日志记录方式、甚至可以计算每个方法的性能。
BLL的调用代码:
- 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);
- }
- }
- }
- 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("订单发送成功!");
- }
- }
- }
在每个独立的上下文环境中应该有一片共享的数据存储区域,以备多个上下文对象访问。这种方便性多半存在于项目比较紧张的修改需求的时候或者加新业务的时候扩展方法用的。
BLL调用代码:
- [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);
- }
- [ContextModule.ContextLogHandler(OperationSort = 1)]
- public void UpdateOrderSingle()
- {
- //直接从当前上下文共享区域读取共享值
- Model.Model_Order ordermodel =
- ContextModule.ContextRuntime.CurrentContextRuntime.GetValue("updateorder") as Model.Model_Order;
- }
对于上下文运行时环境的构建需要考虑到运行时是共享的上下文对象。对于纳入上下文管理的所有对象都需要共享或者说是受控于上下文运行时。
上下文构建:
- /***
- * 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())
- {}
上下文对象的绑定需要延后,不能在对象的构建时就创建上下文。
使用后期绑定动态的切入到执行的上下文中。
调用代码,上下文入口:
- /***
- * 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);
- }
- }
- }
- }
有了上下文的核心原型之后我们可以扩展到分层架构中来,对于分层架构的使用其实很有必要,一般的大型业务系统都是混合的使用模式,可能有C/S、B/S、Mobile终端等等。
对于加入Service层之后BLL、DAL将位于服务之后,对于来自客户端的调用需要经过一些列的身份验证及权限授予。有了WCF之后面向SOA的架构开发变的相对容易点,对安全、性能、负载等等都很完美,所以大部分的情况下我们很少需要控制BLL、DAL的执行运行。
那么没有使用WCF构建分布式的系统时或者是没有分布式的需求就是直接的调用,如WEB的一般开发,从UI到BLL到DAL。或者是普通的Winfrom的项目、控制台项目属于内网的使用,可能就需要控制到代码的执行。
下面我通过演示一个具体的实例来看看到底效果如何。
我以控制台的程序作为演示项目类型,也使用简单的三层架构。
这个再简单不过了吧,为了演示越简单越好,关键是突出重点。
需求:
在DAL对象里面加入一个插入Order实体对象的方法:
- [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.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);
- }
- /***
- * 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();
- }
- }
- }