DDD:管理“工作单元实例”的两种模式
DDD:管理“工作单元实例”的两种模式
当前标签: 架构
续--请思考: 模式的学习和应用--架构是什么? Ambit 2013-04-17 22:51 阅读:296 评论:0
请思考: 模式的学习和应用 Ambit 2013-04-16 09:27 阅读:691 评论:3
软件开发非功能性需求 Ambit 2013-04-14 22:03 阅读:39 评论:0
概念介绍
类图如下:
在常见的用例场景下,类图的对象图如下:
问题 在一个用例执行过程中,如何保证同一个界限上下文内的所有仓储实例可以共享同一个工作单元实例?
解决方案1 仓储采用依赖注入模式 + 使用IOC管理工作单元的生命周期(PerRequest或其它)。
代码示例
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 using Autofac; 8 9 namespace AutoFacStudy 10 { 11 class Program 12 { 13 static void Main( string [] args) 14 { 15 var buider = new ContainerBuilder(); 16 buider.RegisterType<服务> (); 17 buider.RegisterType<仓储A> (); 18 buider.RegisterType<仓储B> (); 19 buider.RegisterType<工作单元> ().InstancePerLifetimeScope(); 20 21 var container = buider.Build(); 22 23 dynamic 服务 = container.Resolve<服务> (); 24 25 // 下边两行代码输出一样 26 Console.WriteLine(服务.仓储A.工作单元.GetHashCode()); 27 Console.WriteLine(服务.仓储B.工作单元.GetHashCode()); 28 } 29 } 30 31 public class 服务 32 { 33 private readonly 仓储A _仓储A; 34 private readonly 仓储B _仓储B; 35 36 public 服务(仓储A 仓储A, 仓储B 仓储B) 37 { 38 _仓储A = 仓储A; 39 _仓储B = 仓储B; 40 } 41 42 public 仓储A 仓储A 43 { 44 get { return _仓储A; } 45 } 46 47 public 仓储B 仓储B 48 { 49 get { return _仓储B; } 50 } 51 } 52 53 public class 工作单元 { } 54 55 public class 仓储A 56 { 57 private readonly 工作单元 _工作单元; 58 59 public 仓储A(工作单元 工作单元) 60 { 61 _工作单元 = 工作单元; 62 } 63 64 public 工作单元 工作单元 65 { 66 get { return _工作单元; } 67 } 68 } 69 70 public class 仓储B 71 { 72 private readonly 工作单元 _工作单元; 73 74 public 仓储B(工作单元 工作单元) 75 { 76 _工作单元 = 工作单元; 77 } 78 79 public 工作单元 工作单元 80 { 81 get { return _工作单元; } 82 } 83 } 84 }
解决方案2 仓储采用服务定位器模式 + 使用服务定位器或简单工厂管理工作单元的生命周期(PerRequest或其它)。
代码示例
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 using Autofac; 8 9 namespace AutoFacStudy 10 { 11 class Program 12 { 13 public static IContainer 服务定位器; 14 15 static void Main( string [] args) 16 { 17 var buider = new ContainerBuilder(); 18 buider.RegisterType<服务> (); 19 buider.RegisterType<仓储A> (); 20 buider.RegisterType<仓储B> (); 21 buider.RegisterType<工作单元> ().InstancePerLifetimeScope(); 22 23 服务定位器 = buider.Build(); 24 25 dynamic 服务 = 服务定位器.Resolve<服务> (); 26 27 // 下边两行代码输出一样 28 Console.WriteLine(服务.仓储A.工作单元.GetHashCode()); 29 Console.WriteLine(服务.仓储B.工作单元.GetHashCode()); 30 } 31 } 32 33 public class 服务 34 { 35 private readonly 仓储A _仓储A; 36 private readonly 仓储B _仓储B; 37 38 public 服务(仓储A 仓储A, 仓储B 仓储B) 39 { 40 _仓储A = 仓储A; 41 _仓储B = 仓储B; 42 } 43 44 public 仓储A 仓储A 45 { 46 get { return _仓储A; } 47 } 48 49 public 仓储B 仓储B 50 { 51 get { return _仓储B; } 52 } 53 } 54 55 public class 工作单元 { } 56 57 public class 仓储A 58 { 59 private readonly 工作单元 _工作单元; 60 61 public 仓储A() 62 { 63 _工作单元 = Program.服务定位器.Resolve<工作单元> (); 64 } 65 66 public 工作单元 工作单元 67 { 68 get { return _工作单元; } 69 } 70 } 71 72 public class 仓储B 73 { 74 private readonly 工作单元 _工作单元; 75 76 public 仓储B() 77 { 78 _工作单元 = Program.服务定位器.Resolve<工作单元> (); 79 } 80 81 public 工作单元 工作单元 82 { 83 get { return _工作单元; } 84 } 85 } 86 }
由此示例可以看出,服务定位器和依赖注入可以混合在一起使用。这个例子我为了简单,服务定位器和IOC容器是同一个实例。
有些系统将服务定位器的实现换成简单工厂模式,他们本质上是一样的(服务定位器是一个万能工厂)。
代码示例
1 public class 工作单元工厂 2 { 3 public static 工作单元 创建() 4 { 5 var 工作单元 = (工作单元)CallContext.GetData( " 工作单元 " ); 6 7 if (工作单元 == null ) 8 { 9 工作单元 = new 工作单元(); 10 CallContext.SetData( " 工作单元 " , 工作单元); 11 } 12 13 return 工作单元; 14 } 15 }
懒人评论:不错,支持一下! 懒人评论:垃圾,还需努力!
框架地址: http://happy.codeplex.com/
博客地址: http://www.cnblogs.com/happyframework/
分类: DDD , .NET
很久以前收藏的一道小题分享给大家~~
智商测试开始:
小明和小强都是张老师的学生,张老师的生日是某月某日,2人都不知道张老师的生日。
生日是下列10组中一天:
3月4日,3月5日,3月8日,6月4日,6月7日,9月1日,9月5日,12月1日,12月2日,12月8日
张老师把月份告诉了小明,把日子告诉了小强,张老师问他们知道他的生日是那一天吗?
小明说:如果我不知道的话,小强肯定也不知道。
小强说:本来我也不知道,但是现在我知道了。
小明说:哦,那我也知道了。
请根据以上对话推断出张老师生日是哪一天?
分类: 智力题~
标签: 程序员题 , 智力题
作者: Leo_wl
出处: http://www.cnblogs.com/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于DDD:管理“工作单元实例”的两种模式的详细内容...