2009-06-11 64 views

回答

5

你所描述的是已經通過NHibernate的提供工作的單位,所以沒有理由做這樣的單元工作。

我們在WCF服務中擁有的是一個更高層次的工作單元,其中包含我們應用於當前工作單元的重要信息。這包括爲我們抽象NHibernate ISession。當你分解它時,你的代碼可以分爲三類

  1. 需要處理Unit Of Work的代碼。誰支持工作單位並不重要。它可能是NHibernate,iBatis或自定義的ORM。所有的代碼需要做的是加載,回滾,保存等。它不會也不應該關心用於這樣做的機制。

  2. 需要直接處理ISession的代碼,因爲它正在執行NHibernate特定的事情。通常這與需要創建的複雜查詢有關。

  3. 不需要知道它在單元工作中運行或訪問ISession。作爲討論的一部分,我們完全可以忽略這一點。

儘管1.中的代碼可能僅僅針對ISession工作,但我們的首選是試圖在代碼中抽象出我們不直接控制或可能改變的東西。有價值的原因有兩個。

  • 當我們開始時,我們並沒有在NHibernate上100%出售。我們正在考慮iBatis或定製的東西。顯然這不再是一個問題。

  • 整個團隊都不是NHibernate的專家,也不是我們想要的。在大多數情況下,人們編寫符合類別1的代碼,而他們所知的全部是我們的工作單元。當類別2中的代碼必須寫入時,它會被理解爲NHibernate的團隊成員編寫。

所以收我會說,單位的類型的工作,你所談論的,不需要我的建議是工作的一個更高層次的單位可以提供很多價值。

+0

ShaneC,我有一個類似的問題,聽起來你已經創建了一個比我的更適合我的需求的工作單元。你可以看看我的問題,並提供你的0.02美元? http://stackoverflow.com/questions/2604762/using-unit-of-work-design-pattern-nhibernate-sessions-in-an-mvvm-wpf – Echiban 2010-04-09 20:31:38

0

如果您正確設置了所有映射(即級聯),則無需執行任何特殊操作,並且ISession也可以正常工作。但是,如果您要編寫3層應用程序,則必須手動對想要在單個事務中執行的數據庫操作進行排序。在「企業應用架構模式」福勒的「參考實現」可以是一個很好的起點:

class UnitOfWork... 

    public void registerNew(DomainObject obj) { 
     Assert.notNull("id not null", obj.getId()); 
     Assert.isTrue("object not dirty", !dirtyObjects.contains(obj)); 
     Assert.isTrue("object not removed", !removedObjects.contains(obj)); 
     Assert.isTrue("object not already registered new", !newObjects.contains(obj)); 
     newObjects.add(obj); 
    } 
    public void registerDirty(DomainObject obj) { 
     Assert.notNull("id not null", obj.getId()); 
     Assert.isTrue("object not removed", !removedObjects.contains(obj)); 
     if (!dirtyObjects.contains(obj) && !newObjects.contains(obj)) { 
     dirtyObjects.add(obj); 
     } 
    } 
    public void registerRemoved(DomainObject obj) { 
     Assert.notNull("id not null", obj.getId()); 
     if (newObjects.remove(obj)) return; 
     dirtyObjects.remove(obj); 
     if (!removedObjects.contains(obj)) { 
     removedObjects.add(obj); 
     } 
    } 
    public void registerClean(DomainObject obj) { 
     Assert.notNull("id not null", obj.getId()); 
    } 
+0

這是一個3層應用程序。但是,我們希望每個用戶請求都是原子的,因此1個用戶請求= 1個數據庫事務。我將處理用戶請求,修改域對象,然後讓NHibernate保留我的聚合根。 – ng5000 2009-06-11 12:00:37

+0

這是對身份映射的抽象。在您創建手動數據映射時非常有用,如Fowler的POEA中所述,但使用NHibernate時,因爲身份映射內置於ISession中。 – Paco 2009-06-11 18:59:37

1

我的工作界面的基本單元包含下列方法 - 初始化 - 提交 - 回滾 - IDisposable.Dispose

我用它了會話和事務管理。 這很有用,因爲我不必一次又一次地爲不同的會話範圍編寫代碼。(每個請求的工作單元,每個請求的系列,每個線程等)

相關問題