2010-01-15 33 views
13

Tôi có thiết lập mẫu kho lưu trữ sử dụng NHibernate. Lớp cơ sở trông giống như sau:Đơn vị công việc và mẫu kho lưu trữ

public interface IUnitOfWork : IDisposable 
{ 
    void Commit(); 
    void Rollback(); 
} 

// generic NHibernate implementation of IUnitOfWork here 

public class NHibernateRepositoryBase<T> : IRepository<T> 
{ 
    private NHibernateUnitOfWork _unitOfWork; 

    public NHibernateRepositoryBase(NHibernateUnitOfWork unitOfWork) 
    { 
     _unitOfWork = unitOfWork; 
    } 
    public T Get(object id) 
    { 
     return _unitOfWork.Session.Get<T>(id); 
    } 

    // ... 
} 

Như bạn có thể thấy, tôi cho phép đơn vị công việc được điền thông qua hàm tạo (sử dụng StructureMap). Tôi đang Populating các đối tượng kho lưu trữ trên dịch vụ web ASP.NET của tôi như vậy:

[WebService(Namespace = "...")] 
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
public class ModuleService : System.Web.Services.WebService 
{ 
    public IUserAccountRepository UserAccountRepo { get; set; } 

    public ModuleService() 
    { 
     // tell IoC to inject properties 
     ObjectFactory.BuildUp(this); 
    } 

    // ... 
} 

Như bạn có thể suy ra, vấn đề của tôi là bằng cách thiết kế, bây giờ tôi đã mất quyền kiểm soát của vòng đời của đơn vị công việc. Trước đây, tôi làm đơn vị làm việc một đối tượng bối cảnh nhạy cảm và kho sẽ có được một tham chiếu đến nó thông qua một cái gì đó như:

public class NHibernateRepositoryBase<T> : IRepository<T> 
{ 
    public T Get(object id) 
    { 
     return NHibernateUnitOfWork.GetCurrent().Session.Get<T>(id); 
    } 

    // ... 
} 

thiết kế trước đây cho phép tôi để kiểm soát vòng đời của các đơn vị làm việc trong mã của tôi bằng cách tạo đơn vị công việc từ UnitOfWorkFactory trong một câu lệnh sử dụng. Tôi đã cố gắng để đặt nhiều công việc trong tay của container IoC, nhưng tôi nghĩ rằng tôi thực sự đã lùi lại một bước. Suy nghĩ của bạn về việc thực hiện là gì?

Trả lời

3

Nó thường là một điều tốt để cho container IoC của bạn xử lý càng nhiều càng tốt. Trên web, một đơn vị mẫu công việc thường được khởi tạo khi bắt đầu yêu cầu và được cam kết ở cuối (cuộn lại nếu có bất kỳ ngoại lệ nào). Bằng cách này, kho lưu trữ của bạn sẽ có một ISession trong constructor thay vì unitofwork. Bằng cách này, kho lưu trữ của bạn sẽ không phải đối phó với cam kết hoặc bất cứ điều gì và sẽ được xử lý tự động cho bạn.

+0

Làm cách nào để xử lý các giao dịch riêng lẻ trong loại thiết lập đó? Giả sử tôi cần chạy hai bộ mã riêng biệt trong cùng một phiên và mỗi phiên có giao dịch riêng. Bạn đề nghị xử lý như thế nào? – Chris

+0

Giao dịch được xử lý thông qua phiên. Bạn không cần bất cứ điều gì khác sau đó tham khảo phiên để sử dụng một giao dịch. –

+3

Phiên NHibernate về cơ bản là một đơn vị công việc tự nó. Lý do để ẩn nó đằng sau đơn vị giao diện công việc của riêng bạn là cơ bản để bạn có thể phơi bày nó theo cách chung cho phần còn lại của ứng dụng (bên ngoài kho lưu trữ của bạn) và không phụ thuộc vào NHibernate. Và điều đó chủ yếu sẽ chỉ là khởi tạo nó khi bắt đầu yêu cầu và cam kết nó ở cuối. –

Các vấn đề liên quan