工作单元模式(UnitOfWork)学习总结

工作单元模式(UnitOfWork)学习总结

工作单元的目标是维护变化的对象列表。使用IUnitOfWorkRepository负责对象的持久化,使用IUnitOfWork收集变化的对象,并将变化的对象放到各自的增删改列表中,

最后Commit,Commit时需要循环遍历这些列表,并由Repository来持久化。

Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems.

      要实现一个银行卡简单转账的功能,Demo框架如下设计:

      工作单元模式(UnitOfWork)学习总结

      代码实现如下:

     

      EntityBase,领域类的基类。

     

  View Code

     IUnitOfWork,复杂维护变化的对象列表,并最后Commit,依次遍历变化的列表,并持久化,这就是Commit的事情。

  View Code

    

    IUnitOfWorkRepository,负责持久化对象。

   

  View Code

   

    UnitOfWork,IUnitOfWork的具体实现。

   

复制代码
 1 using System;

 2 using System.Collections.Generic;

 3 using System.Linq;

 4 using System.Text;

 5 using System.Threading.Tasks;

 6 using System.Transactions;

 7 

 8 namespace Jack.Gao.UnitOfWork.Infrastructure

 9 {

10     public class UnitOfWork:IUnitOfWork

11     {

12         #region Fields

13 

14         private Dictionary<EntityBase, IUnitOfWorkRepository> addedEntities;

15         private Dictionary<EntityBase, IUnitOfWorkRepository> changededEntities;

16         private Dictionary<EntityBase, IUnitOfWorkRepository> removedEntities;

17 

18         #endregion

19 

20         #region Constructor

21 

22         public UnitOfWork()

23         {

24             addedEntities=new Dictionary<EntityBase, IUnitOfWorkRepository>();

25             changededEntities=new Dictionary<EntityBase, IUnitOfWorkRepository>();

26             removedEntities=new Dictionary<EntityBase, IUnitOfWorkRepository>();

27         }

28 

29         #endregion

30 

31         #region Implement IUnitOfWork

32 

33         public void RegisterAdded(EntityBase entityBase, IUnitOfWorkRepository unitOfWorkRepository)

34         {

35             this.addedEntities.Add(entityBase,unitOfWorkRepository);

36         }

37 

38         public void RegisterChangeded(EntityBase entityBase, IUnitOfWorkRepository unitOfWorkRepository)

39         {

40             this.changededEntities.Add(entityBase,unitOfWorkRepository);

41         }

42 

43         public void RegisterRemoved(EntityBase entityBase, IUnitOfWorkRepository unitOfWorkRepository)

44         {

45             this.removedEntities.Add(entityBase,unitOfWorkRepository);

46         }

47 

48         public void Commit()

49         {

50             using (TransactionScope transactionScope=new TransactionScope())

51             {

52                 foreach (var entity in addedEntities.Keys)

53                 {

54                     addedEntities[entity].PersistNewItem(entity);

55                 }

56 

57                 foreach (var entity in changededEntities.Keys)

58                 {

59                     changededEntities[entity].PersistUpdatedItem(entity);

60                 }

61 

62                 foreach (var entity in removedEntities.Keys)

63                 {

64                     removedEntities[entity].PersistDeletedItem(entity);

65                 }

66 

67                 transactionScope.Complete();

68             }

69         }

70 

71         #endregion

72     }

73 }
复制代码

 


   

    BankAccount,继承自领域基类EntityBase。

   

  View Code

  

    IAccountRepository,持久化BankAcount接口

  

  View Code

 

   

    BankAccountService,服务类,实现转账服务。

复制代码
 1 using System;

 2 using System.Collections.Generic;

 3 using System.Linq;

 4 using System.Text;

 5 using System.Threading.Tasks;

 6 using Jack.Gao.UnitOfWork.Infrastructure;

 7 

 8 namespace Jack.gao.UnitOfWork.Domain

 9 {

10     public class BankAccountService

11     {

12         #region Field

13 

14         private IAccountRepository _accountRepository;

15         private IUnitOfWork _unitOfWork;

16 

17         #endregion

18 

19         #region Constructor

20 

21         public BankAccountService(IAccountRepository accountRepository, IUnitOfWork unitOfWork)

22         {

23             this._accountRepository = accountRepository;

24             this._unitOfWork = unitOfWork;

25         }

26 

27         #endregion

28 

29         #region Method

30 

31         public void TransferMoney(BankAccount from, BankAccount to, decimal balance)

32         {

33             if (from.Balance>=balance)

34             {

35                 from.Balance = from.Balance - balance;

36                 to.Balance = to.Balance + balance;

37 

38                 _accountRepository.Save(from);

39                 _accountRepository.Save(to);

40                 _unitOfWork.Commit();

41             }

42         }

43 

44         #endregion

45     }

46 }
复制代码

 

 


    AccountRepository,持久化具体实现,使用ADO.NET实现,也可以使用其他的EF,NHbernate

复制代码
  1 using System;

  2 using System.Collections.Generic;

  3 using System.Linq;

  4 using System.Text;

  5 using System.Threading.Tasks;

  6 using Jack.gao.UnitOfWork.Domain;

  7 using Jack.Gao.UnitOfWork.Infrastructure;

  8 using System.Data.SqlClient;

  9 

 10 namespace Jack.gao.UnitOfWork.Persistence

 11 {

 12     public class AccountRepository:IAccountRepository,IUnitOfWorkRepository

 13     {

 14         #region Field

 15 

 16         private const string _connectionString = @"Data Source=T57649\MSSQLSERVER2012;Initial Catalog=DB_Customer;Integrated Security=True";

 17 

 18         private IUnitOfWork _unitOfWork;

 19 

 20         #endregion

 21 

 22         #region Constructor

 23 

 24         public AccountRepository(IUnitOfWork unitOfWork)

 25         {

 26             this._unitOfWork = unitOfWork;

 27         }

 28 

 29         #endregion

 30 

 31         #region Implement interface IAccountRepository,IUnitOfWorkRepository

 32 

 33         public void Save(BankAccount account)

 34         {

 35             _unitOfWork.RegisterChangeded(account,this);

 36         }

 37 

 38         public void Add(BankAccount account)

 39         {

 40             _unitOfWork.RegisterAdded(account,this);

 41         }

 42 

 43         public void Remove(BankAccount account)

 44         {

 45             _unitOfWork.RegisterRemoved(account,this);

 46         }

 47 

 48         public void PersistNewItem(EntityBase entityBase)

 49         {

 50             BankAccount account = (BankAccount)entityBase;

 51 

 52             string insertAccountSql = string.Format("insert into DT_Account(balance,Id) values({0},{1})", account.Balance, account.Id);

 53 

 54             SqlConnection sqlConnection = new SqlConnection(_connectionString);

 55 

 56             try

 57             {

 58                 sqlConnection.Open();

 59 

 60                 SqlCommand sqlCommand = new SqlCommand(insertAccountSql, sqlConnection);

 61 

 62                 sqlCommand.ExecuteNonQuery();

 63             }

 64             catch (Exception ex)

 65             {

 66                 throw ex;

 67             }

 68             finally

 69             {

 70                 sqlConnection.Close();

 71             }

 72         }

 73 

 74         public void PersistUpdatedItem(EntityBase entityBase)

 75         {

 76             BankAccount account = (BankAccount)entityBase;

 77 

 78             string updateAccountSql = string.Format("update DT_Account set balance={0} where Id={1}", account.Balance,account.Id);

 79 

 80             SqlConnection sqlConnection = new SqlConnection(_connectionString);

 81 

 82             try

 83             {

 84                 sqlConnection.Open();

 85 

 86                 SqlCommand sqlCommand = new SqlCommand(updateAccountSql, sqlConnection);

 87 

 88                 sqlCommand.ExecuteNonQuery();

 89             }

 90             catch (Exception ex)

 91             {

 92                 throw ex;

 93             }

 94             finally

 95             {

 96                 sqlConnection.Close();

 97             }

 98         }

 99 

100         public void PersistDeletedItem(EntityBase entityBase)

101         {

102             BankAccount account = (BankAccount)entityBase;

103 

104             string deleteAccountSql = string.Format("delete from DT_Account where Id={0}", account.Id);

105 

106             SqlConnection sqlConnection = new SqlConnection(_connectionString);

107 

108             try

109             {

110                 sqlConnection.Open();

111 

112                 SqlCommand sqlCommand = new SqlCommand(deleteAccountSql, sqlConnection);

113 

114                 sqlCommand.ExecuteNonQuery();

115             }

116             catch (Exception ex)

117             {

118                 throw ex;

119             }

120             finally

121             {

122                 sqlConnection.Close();

123             }

124         }

125 

126         #endregion

127 

128         #region Method

129 

130         public BankAccount GetAccount(BankAccount account)

131         {

132             account.Balance = 100;

133             return account;

134         }

135 

136         #endregion

137     }

138 }
复制代码

 

    AccountRepositoryTest,测试AccountRepository中的方法

  View Code

 

 
 
分类:  设计模式

你可能感兴趣的:(工作)