Lind.DDD.UoW工作(zuo)單元的實現
工(gong)作(zuo)單元UoW我們幾(ji)乎在任(ren)務(wu)一(yi)(yi)個像樣的(de)框(kuang)(kuang)架里都可(ke)以找到它的(de)足跡,是的(de),對于大型(xing)系(xi)統(tong)來(lai)說,他是很重要(yao)的(de),保(bao)持(chi)數據一(yi)(yi)致性,維持(chi)事務(wu)狀(zhuang)態這都是它要(yao)為(wei)系(xi)統(tong)實現(xian)的(de)功能,而在不同(tong)的(de)框(kuang)(kuang)架里,實現(xian)UoW的(de)機制(zhi)也(ye)是不同(tong)的(de),在Lind.DDD中,采(cai)用了一(yi)(yi)種共同(tong)注(zhu)冊,統(tong)一(yi)(yi)提交(jiao)的(de)方式(shi)來(lai)實現(xian)UoW!
UoW結構圖
我們(men)(men)來看(kan)一下大叔(shu)工(gong)作單元的代(dai)碼實(shi)現,首先看(kan)一下IUnitOfWorkRepository,我們(men)(men)的倉儲接口會實(shi)現它,以便之后我們(men)(men)的倉儲對象可以添加(jia)到(dao)工(gong)作單元里
/// <summary> /// 工作(zuo)單(dan)元中倉(cang)儲接口CRUD操作(zuo) /// 需要使用工作單元的倉儲,需要實現本接口(IRepository,IExtensionRepository) /// </summary> public interface IUnitOfWorkRepository { /// <summary> /// 添加實體(ti) /// </summary> /// <param name="item"></param> void UoWInsert(IEntity item); /// <summary> /// 更新實體(ti) /// </summary> /// <param name="item"></param> void UoWUpdate(IEntity item); /// <summary> /// 移(yi)除實體 /// </summary> /// <param name="item"></param> void UoWDelete(IEntity item); }
接(jie)(jie)(jie)下來,我們再來說一下IUnitOfWork接(jie)(jie)(jie)口,它是(shi)工作單(dan)元入口的(de)接(jie)(jie)(jie)口,有(you)添加(jia)到(dao)單(dan)元和(he)提交單(dan)元兩個方法(fa),使用簡單(dan)明了(le),內(nei)部(bu)有(you)字典對象,用來存儲要(yao)提交的(de)操作,這也(ye)是(shi)工作單(dan)元的(de)核心(xin),IEntity是(shi)實體的(de)標識接(jie)(jie)(jie)口,所(suo)有(you)實體都要(yao)繼承它,而(er)IUnitOfWorkRepository是(shi)倉(cang)儲的(de)標識接(jie)(jie)(jie)口,所(suo)以倉(cang)儲接(jie)(jie)(jie)口都要(yao)繼承它。
/// <summary> /// 工作(zuo)單元 /// 所有數(shu)據上下(xia)(xia)文(wen)對象都應(ying)該(gai)繼承它,面向倉(cang)儲的上下(xia)(xia)文(wen)應(ying)該(gai)與具(ju)體實現(存儲介(jie)質,ORM)無關(guan) /// </summary> public interface IUnitOfWork { /// <summary> /// 向工作單元(yuan)中注冊變更 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="entity"></param> /// <param name="type"></param> /// <param name="repository"></param> void RegisterChangeded(IEntity entity, SqlType type, IUnitOfWorkRepository repository); /// <summary> /// 向數據(ju)庫(ku)提交變(bian)更 /// </summary> void Commit(); }
我們來看一下,大叔是如何實現IUnitOfWork接口的吧
/// <summary> /// 工(gong)作單(dan)元,主要用于管理事(shi)務性操作 /// Author:Lind.zhang /// </summary> public class UnitOfWork : IUnitOfWork { #region Fields /// <summary> /// 操作行為字典 /// </summary> private IDictionary<IEntity, IUnitOfWorkRepository> insertEntities; private IDictionary<IEntity, IUnitOfWorkRepository> updateEntities; private IDictionary<IEntity, IUnitOfWorkRepository> deleteEntities; #endregion #region Constructor public UnitOfWork() { insertEntities = new Dictionary<IEntity, IUnitOfWorkRepository>(); updateEntities = new Dictionary<IEntity, IUnitOfWorkRepository>(); deleteEntities = new Dictionary<IEntity, IUnitOfWorkRepository>(); } #endregion #region IUnitOfWork 成員 /// <summary> /// 事務提交 /// </summary> public void Commit() { try { using (TransactionScope transactionScope = new TransactionScope()) { foreach (var entity in insertEntities.Keys) { insertEntities[entity].UoWInsert(entity); } foreach (var entity in updateEntities.Keys) { updateEntities[entity].UoWUpdate(entity); } foreach (var entity in deleteEntities.Keys) { deleteEntities[entity].UoWDelete(entity); } transactionScope.Complete();//提(ti)交事務,程(cheng)序中如果(guo)出錯,這(zhe)行無法執行,即事務不會被(bei)提(ti)交,這(zhe)就類似于rollback機制 } } catch (Exception ex) { Logger.LoggerFactory.Instance.Logger_Error(ex); } } /// <summary> /// 注冊數據變更(geng) /// </summary> /// <typeparam name="T"></typeparam> /// <param name="entity"></param> /// <param name="type"></param> public void RegisterChangeded(IEntity entity, SqlType type, IUnitOfWorkRepository repository) { switch (type) { case SqlType.Insert: insertEntities.Add(entity, repository); break; case SqlType.Update: updateEntities.Add(entity, repository); break; case SqlType.Delete: deleteEntities.Add(entity, repository); break; default: throw new ArgumentException("you enter reference is error."); } } #endregion }
工作單(dan)元在調用時(shi)也(ye)是非(fei)常方便的,兩(liang)步完(wan)成,第一注意動(dong)作,第二提交(jiao)事務,下面看一下DEMO的代碼(ma)片斷(duan)
unitOfWork.RegisterChangeded(entity, SqlType.Update, userRepository); var userExtension = userExtRepository.Find(entity.Id); userExtension.NickName = Request.Form["UserExtension.NickName"]; userExtension.School = Request.Form["UserExtension.School"]; unitOfWork.RegisterChangeded(userExtension, SqlType.Update, userExtRepository); unitOfWork.Commit();
OK,對于工作單元的探討今(jin)天(tian)就先(xian)說到這(zhe)里(li),以后肯定還(huan)是機會去(qu)研(yan)究的!