2009-09-02 64 views
3

我正在嘗試將我的域模型編寫爲儘可能持久的域模型。我現在唯一要做的就是標記每個屬性和方法virtual,因爲NHibernate要求延遲加載。NHibernate ITransaction和純粹域名模型

在我域模型組件我定義了一些庫接口:

public interface IRepository<TEntity> where TEntity : EntityBase { 
    TEntity Get(int id); 
    /* ... */ 
} 
public interface IProductRepository : IRepository<Product> { ... } 

然後,我有一個數據彙編。這個會引用NHibernate,它知道它的存在。這是實現那些存儲庫接口的程序集:

public abstract class Repository<TEntity> : IRepository<TEntity> { 
    public TEntity Get(ind id) { ... } 
    /* ... */ 
} 
public class ProductRepository : Repository<Product>, IProductRepository { 
    /* ... */ 
} 

等等。

現在我想實現交易功能到我的資料庫。爲此,我會在我的IRepository接口上添加一個BeginTransaction方法。但是,我無法將其返回類型定義爲NHibernate.ITransaction,因爲我想保持領域模型持久化無知,並且不會被迫從我的領域模型組件中引用NHibernate的程序集。

你會怎麼做?

你會簡單地實現void BeginTransaction(),一個void Commit(),並且在接口上void RollBack()方法,讓庫執行管理ITransaction對象內部

或者你會找到一種方法公開ITransaction對象讓客戶直接用它來管理事務,而不是使用存儲庫的方法?

謝謝!

回答

2

您可以看看Sharp Architecture,它已經實現了您所談論的所有事情,包括具有事務支持的通用存儲庫。那裏的解決方案是IRepository具有封裝事務的DbContext屬性(它實際上是一個接口)。 這是您描述的第一個選項(隱藏NHibernate的自定義事務接口)。它運作良好。

我猜你甚至可以重新使用S#arp代碼,無論你是否打算使用完整的框架。

0

IMO事務應始終在業務邏輯中開始和結束,換句話說,事務應該從服務層開始,而不是存儲庫層,並且存儲庫應該在事務中使用它自己,理想情況下這將隱式完成。

現在,如果你正在使用NH那麼如果你的服務和存儲庫共享相同的「會話」(他們應該),那麼你可以稱之爲「的BeginTransaction」在業務層和提交或根據需要回滾:

例如,想象這上的服務的方法,包括:

public void RegisterCustomer(Customer customer) 
    { 
     try 
     { 
      using(var transaction = _session.BeginTransaction()) 
      { 
       _customerRepository.Save(customer); 
       _customerSurveyRepository.Save(customerSurvey); 
       // DO What ever else you want... 
       transaction.Commit(); 
      } 
     } 
     catch (Exception exn) 
     { 
      throw new AMException(FAILED_REGISTRATION, exn); 
     } 
    } 

儲存庫如何獲取到相同的會話的引用可以通過在構造注入或通過使用SessionFactory來獲取當前要解決會議...