zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    The 4 Most Important Skills for a Software Developer
    Youth is not a time of life, it is a state of mind——青春不是一段年华,而是一种心境
    英雄所见略同——每个人都有的一套价值体系观念
    28法则————10分钟休息胜过半小时努力
    离职员工心声
    员工必备素质、能力——职场精英
    安卓sqlite数据库的使用
    安卓adb命令的使用
    windows使用命令行,提高效率
    命令行编译java文件(含第三方jar包)
  • 原文地址:https://www.cnblogs.com/happyframework/p/3026812.html
Copyright © 2011-2022 走看看