.NET面向上下文、AOP架构模式(概述)
1. 上下文概述
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的执行代码:
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 }
上述代码是我模拟一个上下文的执行过程。
在每个独立的上下文环境中应该有一片共享的数据存储区域,以备多个上下文对象访问。这种方便性多半存在于项目比较紧张的修改需求的时候或者加新业务的时候扩展方法用的。BLL调用代码:
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执行代码:
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 }
对于上下文运行时环境的构建需要考虑到运行时是共享的上下文对象。对于纳入上下文管理的所有对象都需要共享或者说是受控于上下文运行时。
上下文构建:
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 }
1 using (ContextModule.ContextRuntime.BeginContextRuntime()) 2 { 3 4 }
通过Using的方式我们开始上下文生命周期。
上下文对象的绑定需要延后,不能在对象的构建时就创建上下文。
使用后期绑定动态的切入到执行的上下文中。
调用代码,上下文入口:
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实体对象的方法:
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 }
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 }
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 }
执行效果:
会先执行日志的记录,然后要求我们输入用户凭证才能继续执行下面的方法。