1. 程式人生 > >Unit Of Work--工作單元(二)

Unit Of Work--工作單元(二)

回顧

上一篇我們根據工作單元的原理基於ADO.NET進行了簡單的實現,但是當專案需求發生變化的時候,比如需要引入ORM框架又要相容當前ADO.NET實現的方式時,先前的實現就無法滿足這個需求了。

話就不多說了,我們就跟據當前的需求變化來重構工作單元吧。

重構UnitOfWork

首先我們看看原先實現的工作單元提取出來的介面,程式碼如下:

public interface IUnitOfWork
{
    void RegisterAdd(string sql, params IDataParameter[] parameters);                             
    void
RegisterSave(string sql, params IDataParameter[] parameters); void RegisterRemove(string sql, params IDataParameter[] parameters); void Comit(); }

由於需求需要相容ORM和ADO.NET方式,而以上的介面僅僅支援ADO.NET的方式,因此介面需要改變,例如:

//其他程式碼省略
void RegisterAdd(object
entity);

觀察以上的修改會發現如果要滿足需求,則需要判斷是ADO.NET或者是ORM的操作,那麼就有了兩種不同的職責,這顯然是不合理的,但是如果我們將ADO.NET和ORM還是讓對應的資料層類去實現的話,就符合單一責任了,於是經過以上分析,就可以對以上的介面做進一步的修改了,大致程式碼如下:

//其他程式碼省略
void RegisterAdd(object entity, IUnitOfWorkRepository repository);

按照這個思路的話,這個IUnitOfWorkRepository的方法數量則會跟IUnitOfWork基本相同(沒有Commit),一個是註冊,而另一個則是實際的操作,因此介面程式碼則會跟第一次改為object

的相同了,程式碼如下:

public interface IUnitOfWorkRepository
{
    void ExecuteAdd(object entity);                             
    void ExecuteSave(object entity);                           
    void ExecuteRemove(object entity);
}

有了以上的改變之後,就可以實現IUnitOfWork了,程式碼結構上還是跟SQLUnitOfWork類似的,差別是原先是使用一個List<SQLEntity>來儲存所有的CUD操作,但是現在必須要區分出不同型別的操作,因此需要有分別儲存CUD的容器,大致程式碼如下:

public class UnitOfWork : IUnitOfWork
{
    private Dictionary<object, IUnitOfWorkRepository> m_addList = new Dictionary<object, IUnitOfWorkRepository>();

    private Dictionary<object, IUnitOfWorkRepository> m_saveList =new Dictionary<object, IUnitOfWorkRepository>();

    private Dictionary<object, IUnitOfWorkRepository> m_removeList = new Dictionary<object, IUnitOfWorkRepository>();

    public void RegisterAdd(object entity, IUnitOfWorkRepository repository)
    {
        if (!this.m_addList.ContainsKey(entity))
            this.m_addList.Add(entity, repository);
    }

    public void RegisterSave(object entity, IUnitOfWorkRepository repository)
    {
        if (!this.m_saveList.ContainsKey(entity))
            this.m_saveList.Add(entity, repository);
    }

    public void RegisterRemove(object entity, IUnitOfWorkRepository repository)
    {
        if (!this.m_removeList.ContainsKey(entity))
            this.m_removeList.Add(entity, repository);
    }

    public void Commit()
    {
        using (TransactionScope trans = new TransactionScope())
        {
            foreach (var entity in this.m_addList.Keys)
            {
                this.m_addList[entity].ExecuteAdd(entity);
            }

            foreach (var entity in this.m_saveList.Keys)
            {
                this.m_saveList[entity].ExecuteSave(entity);
            }

            foreach (var entity in this.m_removeList.Keys)
            {
                this.m_removeList[entity].ExecuteRemove(entity);
            }
            trans.Complete();
        }
    }
}

到這裡我們就將工作單元重構工作完成了,接下來就可以根據IUnitOfWorkRepository派生出基於ADO.NET和ORM的實現了。

重構SchoolRepository

首先我們先看一下重構後的程式碼:

class SchoolRepository : IRepository, IUnitOfWorkRepository
{
    private IDbConnection m_connection = null;
    private IUnitOfWork m_uow = null;

    public SchoolRepository(IDbConnection connection, IUnitOfWork uow)
    {
        this.m_connection = connection;
        this.m_uow = uow;
    }

    public void Add(object entity)
    {
        this.m_uow.RegisterAdd(entity, this);
    }

    public void Save(object entity)
    {
        this.m_uow.RegisterSave(entity, this);
    }

    public void Remove(object entity)
    {
        this.m_uow.RegisterRemove(entity, this);
    }

    public void ExecuteAdd(object entity)
    {
        School school = entity as School;
        using (IDbCommand cmd = this.m_connection.CreateCommand())
        {
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "insert school values(@id, @name)";
            cmd.Parameters.Add(new SqlParameter("@id", school.Id));
            cmd.Parameters.Add(new SqlParameter("@name", school.Name));
            cmd.ExecuteNonQuery();
        }
    }

    public void ExecuteSave(object entity)
    {
        //程式碼略
    }

    public void ExecuteRemove(object entity)
    {
        //程式碼略
    }
}

IRepository是資料層的基礎介面,從程式碼中我們看到原先CUD的方法被拆分到了CUD和ExecuteXXX方法中去了,CUD方法負責呼叫IUnitOfWork的介面,而ExecuteXXX則實現具體的資料庫操作

基於NHibernate的IUnitOfWorkRepository實現

先看程式碼吧

class SchoolRepository : IRepository, IUnitOfWorkRepository
{
    private IUnitOfWork m_uow = null;

    public SchoolRepository(IDbConnection connection, IUnitOfWork uow)
    {
        this.m_uow = uow;
    }

    public void Add(object entity)
    {
        this.m_uow.RegisterAdd(entity, this);
    }

    public void Save(object entity)
    {
        this.m_uow.RegisterSave(entity, this);
    }

    public void Remove(object entity)
    {
        this.m_uow.RegisterRemove(entity, this);
    }

    public void ExecuteAdd(object entity)
    {
        SessionFactory.CurrentSession.Add(entity);
    }

    public void ExecuteSave(object entity)
    {
        //程式碼略
    }

    public void ExecuteRemove(object entity)
    {
        //程式碼略
    }
}

從基於NHibernate的實現中,我們可以看到ExecuteXXX的方法都是去呼叫NHibernateSession的相關方法的。

結尾

到此資料層就只差查詢了,下次會分享一下關於查詢的模式。

相關推薦

Unit Of Work--工作單元()

回顧 上一篇我們根據工作單元的原理基於ADO.NET進行了簡單的實現,但是當專案需求發生變化的時候,比如需要引入ORM框架又要相容當前ADO.NET實現的方式時,先前的實現就無法滿足這個需求了。 話就不多說了,我們就跟據當前的需求變化來重構工作單元吧。

Unit Of Work--工作單元

簡介   最近忙著新專案的架構,已經有一段時間沒有更新部落格了,一直考慮著要寫些什麼,直到有一天跟朋友談起他們公司開發資料層遇到的一些問題時,我想應該分享一些專案中使用的資料訪問模式。 雖然最近一直都在使用Go語言開發資料伺服器,但是本篇文章用到的語言仍然是C#,文章內提供的程式碼僅僅是分享如何使用工作單元

ABP(現代ASP.NET樣板開發框架)系列之12、ABP領域層——工作單元Unit Of work

基於DDD的現代ASP.NET開發框架--ABP系列之12、ABP領域層——工作單元(Unit Of work) ABP是“ASP.NET Boilerplate Project (ASP.NET樣板專案)”的簡稱。 通用連線和事務管理方法 連線和事務管理是使用資料庫的應用程

Axon Framework工作單元,The Unit of Work

工作單元是Axon Framework的一個重要的概念,雖然在大多數情況下你可能不太直接與它互動。訊息的處理被視為一個獨立單元。工作單元的目的是在處理一條訊息(命令或事件)期間去協調行為的執行。元件可以在工作單元每一個階段執行註冊行為,如onPrepareCom

ABAP術語-LUW (Logical Unit of Work)

從數據 ble commit entire 工作 unit gic https view LUW (Logical Unit of Work) 原文:http://www.cnblogs.com/qiangsheng/archive/2008/03/04/1089637.h

ASP.NET MVC3.0+ JqGrid+Unit Of Work+ Repository/ EF 4.1 CRUD應用 (多層結構)

ManageContacts.cs public class ManageContacts { public IEnumerable<Contact> GetContacts() { IEnumerable<Contact&

ABP原始碼分析十:Unit Of Work

ABP以AOP的方式實現UnitOfWork功能。通過UnitOfWorkRegistrar將UnitOfWorkInterceptor在某個類被註冊到IOCContainner的時候,一併新增到該類在容器中對應的ComponentModel的Interceptors集合中。總結一句話就是,UOW的功能是通過

ABP官方文檔翻譯 3.6 工作單元

readonly ont 重要 mic 不改變 foreach 行為 你在 pmod 工作單元 介紹 ABP中的連接和事務管理 傳統的工作單元方法 控制工作單元 UnitOfWork特性 IUnitOfWorkManager 工作單

用python闡釋工作量證明(proof of work)

import trac 挖礦 hash 耗電 hid bre 方程 ng- 了解比特幣的都知道挖礦非常耗電,這是由於比特幣用到了工作量證明. 工作量證明是指系統為達到某目標而設置的工作度量方法.一開始是用在網絡攻防上,大大提高攻擊者的計算量,攻擊成本也就上去了. 工作

Android 基於Netty的消息推送方案之概念和工作原理()

img b2c 決定 watermark net nios 通道 感覺 art 上一篇文章中我講述了關於消息推送的方案以及一個基於Netty實現的一個簡單的Hello World。為了更好的理解Hello World中的代碼,今天我來解說一下關於Netty中一些概念和工

深入解析瀏覽器的幕後工作原理() 呈現引擎

div 分享 image ima 好的 clas logs 指令 開放源代碼 呈現引擎   本文所討論的瀏覽器(Firefox、Chrome 瀏覽器和 Safari)是基於兩種呈現引擎構建的。Firefox 使用的是 Gecko,這是 Mozilla 公司“自制”的呈現

PHP面向對象之工作單元

pan cte dsn per array 特定 back fun sel /* 工作單元 這個模式涉及到了領域模型、數據映射器和標識映射,這裏就統一進行整理和回顧了。 $venue = new \woo\domain\Venue(null,"The Green Tree

LeetCode 543. Diameter of Binary Tree (叉樹的直徑)

tween res edge public level 距離 sent java dot Given a binary tree, you need to compute the length of the diameter of the tree. The diamet

WHAT KINDS OF WORK CAN FREELANCE ENGINEERS DO?

Graduating from an engineering college is a big step. The next big step is finding a suitable job . The only problem is that a because job there ve

解析ABP框架中的事務處理和工作單元,ABP事務處理

回滾 rtu 新的 ola 方式 repo amp assigned 對象 通用連接和事務管理方法連接和事務管理是使用數據庫的應用程序最重要的概念之一。當你開啟一個數據庫連接,什麽時候開始事務,如何釋放連接...諸如此類的。 正如大家都知道的,.Net使用連接池(conne

探究Entity Framework如何在多個倉儲層實例之間實現工作單元的實現及原理

事務日誌 方法 tran action opera and 底層 下載 none 前言   1、本文的前提條件:EF上下文是線程唯一,EF版本6.1.3。   2、網上已有相關API的詳細介紹,本文更多的是作為我自己的個人學習研究記錄。 疑問   用反編譯工具翻開D

How Javascript works (Javascript工作原理) () 引擎,運行時,如何在 V8 引擎中書寫最優代碼的 5 條小技巧

tco master 一次 指定 ava 技術分享 將不 創建 跳轉 個人總結: 一個Javascript引擎由一個標準解釋程序,或者即時編譯器來實現。 解釋器(Interpreter): 解釋一行,執行一行。 編譯器(Compiler): 全部編譯成機器碼,統一執行。(減

English trip -- Review Unit8 Work 工作

ech 服務 iter class 中間 design right 是什麽 出租車 工作一般詢問對方的工作情況的方式: What job is it? 它的工作是什麽? You‘re a engineer? 你是工程師? Right 是的 What do

Android 基於Netty的訊息推送方案之概念和工作原理()

上一篇文章中我講述了關於訊息推送的方案以及一個基於Netty實現的一個簡單的Hello World,為了更好的理解Hello World中的程式碼,今天我來講解一下關於Netty中一些概念和工作原理的內容,如果你覺得本篇文章有些枯燥,請先去閱讀《Android 基於Netty的訊息推送方案之Hell

.net core2.x - 關於工作單元(UnitOfWork) 模式

概要:在搭建框架,順手說下寫下,關於unitofwork,可能你理解了,可能你還不理解,可能與不可能不是重點,重點是感興趣就看看吧。 1.工作單元(unitofowork)是什麼(後面簡寫uow)?   Maintains a list of objects affected by a busi