5

我已經能夠實現一個很酷的工作單元來處理實體框架。UnitOfWork實現

我想出了..

public class UnitOfWork : IUnitOfWork 
    { 
     private Database _database; 
     private IDatabaseFactory _databaseFactory; 

     private DbTransaction transaction; 

     public UnitOfWork(IDatabaseFactory databaseFactory) 
     { 
      _databaseFactory = databaseFactory; 
      _database = Database; 

      transaction = _database.Database.Connection.BeginTransaction(); 
     } 

     public Database Database 
     { 
      get { return _database ?? (_database = _databaseFactory.Get()); } 
     } 

     public void Dispose() 
     { 
      try 
      { 
       _database.SaveChanges(); 
       transaction.Commit(); 
      } 
      catch (Exception ex) 
      { 
       transaction.Rollback(); 
      } 
     } 
    } 

我敢肯定每個人都嫉妒本單位工作的現在。 (Kidding)

但是我在這個服務層有一點設計問題。

public class JournalService : IJournalService 
    { 
     IJournalRepository _journalRepository; 

     public JournalService(IJournalRepository journalRepository) 
     { 
      _journalRepository = journalRepository; 
     } 

     public void AjouterJournal(Journal j) 
     { 
      [B]using (IUnitOfWork uow = new UnitOfWork())[/B] 
      { 
       var journal = new Journal(); 
       journalRepository.AddJournal(journal); 

      } 
     } 
    } 

問題是工作單元需要數據庫注入,所以我不能創建它的一個實例。我無法直接在服務層提供一個工作單元,因爲這樣做毫無意義,因爲工作單元需要一次性使用。

而且由於我使用知識庫來添加我的東西,因此無需直接訪問工作單元,無論如何都會自動進行保存。

我可以在我的服務層注入IDatabaseFactory,但想法是不要在那裏使用它。其實服務層不應該知道它。

UnitOfWork工廠怎麼樣?

任何想法或建議我怎麼能解決這個問題?

謝謝。

+0

`UnitOfWork`工廠似乎工作。但問題在於你如何向`UnitOfWorkFactory`提供`IDatabaseFactory`。 – yuxhuang 2011-02-05 17:09:54

+0

構造函數中的DI注入? – Rushino 2011-02-05 17:18:23

回答

7

如果您想使用您當前的體系結構,您應該將UnitOfWork注入服務。您的服務不會對UnitOfWork實現具有內部(隱藏)依賴性,並且可以更好地進行測試。它與許多面向對象體系結構的原則緊密相連。

此外,此實現僅適用於簡單的CRUD操作。在更復雜的服務中,您最終將組成多個操作(可能來自multipe服務),每個操作都將使用UnitOfWork進行操作。在一個業務操作中調用多個SaveChanges(和事務)可能不是您通常想要的 - 在這種情況下,您只想從一些頂級服務或服務調用者調用一次SaveChanges。典型的情況是單一業務操作只有一個工作單元,但是您可以在業務操作中執行大量服務操作。

另一個含義是構建您的存儲庫。他們可能需要訪問數據庫,不是嗎?所以你可能已經將UoW注入到倉庫構造函數中了。如果你這樣做,你可以避免UoW和基本服務之間的關係。