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

概念介绍

类图如下:

DDD:管理“工作单元实例”的两种模式

在常见的用例场景下,类图的对象图如下:

DDD:管理“工作单元实例”的两种模式

问题

在一个用例执行过程中,如何保证同一个界限上下文内的所有仓储实例可以共享同一个工作单元实例?

解决方案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 }
复制代码
 
分类:  DDD.NET

很久以前收藏的一道小题分享给大家~~

智商测试开始:

小明和小强都是张老师的学生,张老师的生日是某月某日,2人都不知道张老师的生日。
生日是下列10组中一天:
3月4日,3月5日,3月8日,6月4日,6月7日,9月1日,9月5日,12月1日,12月2日,12月8日
张老师把月份告诉了小明,把日子告诉了小强,张老师问他们知道他的生日是那一天吗?
小明说:如果我不知道的话,小强肯定也不知道。
小强说:本来我也不知道,但是现在我知道了。
小明说:哦,那我也知道了。

请根据以上对话推断出张老师生日是哪一天?

 
 
分类:  智力题~
标签:  程序员题智力题

你可能感兴趣的:(智力题,程序员题)