7

Tôi đã nêu ra câu hỏi này trước nhưng tôi vẫn đang đấu tranh để tìm một ví dụ mà tôi có thể xoay đầu (xin đừng chỉ cho tôi xem dự án Kiến trúc S # arp mà không có ít nhất một số hướng).Làm thế nào tôi có thể thực hiện phiên NHibernate cho mỗi yêu cầu mà không có sự phụ thuộc vào NHibernate?

Cho đến nay tôi đã đạt được sự thiếu hiểu biết liên tục gần trong dự án web của mình. lớp kho của tôi (trong dự án dữ liệu của tôi) có một ISession trong constructor:

public class ProductRepository : IProductRepository 
{ 
    private ISession _session; 
    public ProductRepository(ISession session) { 
     _session = session; 
    } 

Trong global.asax tôi vạch trần phiên hiện tại và đang tạo ra và xử lý session trên BeginRequest và EndRequest (đây là nơi mà tôi có sự phụ thuộc vào NHibernate):

public static ISessionFactory SessionFactory = CreateSessionFactory(); 

    private static ISessionFactory CreateSessionFactory() { 
     return new Configuration() 
      .Configure() 
      .BuildSessionFactory(); 
    } 

    protected MvcApplication() { 
     BeginRequest += delegate { 
      CurrentSessionContext.Bind(SessionFactory.OpenSession()); 
     }; 
     EndRequest += delegate { 
      CurrentSessionContext.Unbind(SessionFactory).Dispose(); 
     }; 
    } 

và cuối cùng đăng ký StructureMap tôi:

public AppRegistry() { 
     For<ISession>().TheDefault 
      .Is.ConstructedBy(x => MvcApplication.SessionFactory.GetCurrentSession()); 

     For<IProductRepository>().Use<ProductRepository>(); 
    } 

có vẻ như tôi cần phải triển khai chung riêng của tôi về ISession và ISessionFactory mà tôi có thể sử dụng trong dự án web của tôi và tiêm vào kho của tôi?

Vì vậy, chỉ cần làm rõ - Tôi đang sử dụng NHibernate trong lớp kho lưu trữ của mình và muốn sử dụng yêu cầu phiên cho mỗi (http). Vì vậy tôi đang tiêm một ISession vào các nhà xây dựng kho lưu trữ của tôi (sử dụng structuremap). Hiện nay để tạo và xử lý các phiên trong mỗi yêu cầu tôi đã phải tham khảo NHibernate từ dự án web của tôi. Đây là sự phụ thuộc tôi muốn loại bỏ.

Cảm ơn, Bến

+6

NHibernate là theo tôi không phải là một phụ thuộc xấu. –

+0

Cuộc hội thoại dự án web của tôi với kho lưu trữ và NHibernate là sự phụ thuộc của kho lưu trữ. Nếu nó không phải là một thực tế là tôi muốn phiên mỗi yêu cầu thì tôi chỉ có thể mở các phiên của tôi bên trong lớp kho lưu trữ. Tuy nhiên, tôi muốn phiên mỗi yêu cầu nhưng tôi không muốn dự án web của tôi gắn với NHibernate. –

+2

Marcouiller: Nó vẫn là một sự phụ thuộc. Sự phụ thuộc là sự phụ thuộc. Nếu Ben muốn chuyển ứng dụng của mình sang CouchDB hoặc MongoDB hoặc sử dụng cơ sở dữ liệu đối tượng trong bộ nhớ thì sao? –

Trả lời

3

Tại sao bạn không tạo ra một IHttpModule và thực hiện sáng tạo của bạn và xử lý đó (có thể là trong Begin_Request và các sự kiện End_Request), nhưng đặt IHttpModule của bạn bên trong dự án mà có sự phụ thuộc NHibernate của bạn . ví dụ.

namespace MyWebApp.Repository.NHibernateImpl 
{ 
    public class NHibernateModule : IHttpModule 
    { 
     public void Init(HttpApplication context) 
     { 
      context.BeginRequest += new EventHandler(Context_BeginRequest); 
      context.EndRequest += new EventHandler(Context_EndRequest); 
     } 

     private void Context_BeginRequest(object sender, EventArgs e) 
     { 
      // Create your ISession 
     } 

     private void Context_EndRequest(object sender, EventArgs e) 
     { 
      // Close/Dispose your ISession 
     } 

     public void Dispose() 
     { 
      // Perhaps dispose of your ISessionFactory here 
     } 
    } 
} 

Có thể có cách tốt hơn, tôi cũng muốn biết điều này, vì vậy, có đề xuất thay thế nào không?

+0

đây là tuyến đường tôi bắt đầu đi xuống nhưng giống như bạn tôi quan tâm nếu có là một cách tốt hơn (nhiều DI thân thiện hơn) để làm điều này. –

+0

@Ben - Nhưng nó không phải là một phụ thuộc xấu xấu như bạn sẽ không phải tham khảo các đối tượng này từ bạn không tham chiếu nó trong dự án web của bạn. Tất cả những gì bạn phải làm là cấu hình trong web.config của bạn. Có chuyện gì vậy?Nếu bạn đã định cấu hình vùng chứa DI của mình qua XML, bạn cũng sẽ phải nhập nó. – jfneis

+0

@jfneis - bạn đã có một ví dụ hoàn chỉnh về việc sử dụng một HttpModule - tôi đặc biệt quan tâm đến cách tôi vẫn có thể tiêm phiên của tôi vào kho lưu trữ và liệu các giao dịch có được xử lý khác nhau hay không. –

0

Cảm ơn sự giúp đỡ của mọi người từ trước tới nay. Một nghiên cứu thêm một chút đã dẫn tôi đến dự án Burrow NHibernate.

Từ FAQ dự án (http://nhforge.org/wikis/burrow/faq.aspx):

Burrow là một trọng lượng trung ánh sáng được phát triển để hỗ trợ các ứng dụng Net sử dụng NHibernate (có lẽ cũng gọi là NH trong bài viết này) như khuôn khổ ORM. Sử dụng Asp.net với NHibernate có thể là một thách thức bởi vì thực tế là NHibernate là một môi trường nhà nước trong khi Asp.net là một khuôn khổ không trạng thái. Burrow có thể giúp giải quyết xung đột này bằng cách cung cấp quản lý phiên/giao dịch nâng cao và thông minh và các điều kiện khác.

Tôi phải nhảy qua một vài vòng để làm cho nó hoạt động trong dự án của tôi. Kể từ khi phát hành hiện tại sử dụng một phiên bản cũ của NHibernate tôi đã phải tải về latest source từ thân cây, mở trong VS, thêm tài liệu tham khảo để phiên bản mới nhất của NHibernate và biên dịch lại (may mắn không có lỗi).

Tôi đã thử nghiệm NHibernate Burrow theo một số cách.

1) Tiếp tục tiêm ISession vào kho của tôi

Để làm điều này, tôi đã có thêm tài liệu tham khảo để NHibernate, NHibernate.Burrow và NHibernate.Burrow.WebTùy chỉnh cho dự án MVC của tôi.

Trong web.config tôi phải thiết lập Burrow (xem http://nhforge.org/wikis/burrow/get-started.aspx) và sau đó trong registry StructureMap tôi thêm như sau:

 For<ISession>() 
      .TheDefault.Is 
      .ConstructedBy(x => new NHibernate.Burrow.BurrowFramework().GetSession());   

Tôi thích phương pháp này vì nó có nghĩa là kho của tôi (hoặc điều khiển) không cùng với Burrow. Tôi không thực sự thích thực tế là tôi phải tham khảo ba hội đồng trong dự án web của tôi nhưng ít nhất tôi mất mã để quản lý phiên - tất cả đều được xử lý bởi Burrow.

2) Cách tiếp cận thứ hai sẽ được thiết lập ISession trong nhà xây dựng kho lưu trữ của tôi như vậy:

public ProductRepository() : 
     this(new BurrowFramework().GetSession()) { } 

    public ProductRepository(ISession session) { 
     _session = session; 
    } 

tôi vẫn có thể ghi đè lên ISession làm kho của tôi kiểm chứng. Sau đó tôi có sự phụ thuộc trực tiếp vào Burrow nhưng có lẽ đây không phải là một điều xấu?

Về mặt cộng, cụm duy nhất tôi cần tham khảo từ dự án web của tôi là NHibernate.Burrow.WebUtils.

Quan tâm để xem người nào sẽ đi đến và tại sao.

2

Theo tôi, bạn nên nắm lấy ISession và làm việc trực tiếp với nó. Vấn đề với việc triển khai nhiều phiên mỗi yêu cầu là chúng trì hoãn việc thay đổi cơ sở dữ liệu cho đến khi kết thúc yêu cầu HTTP. Nếu giao dịch thất bại, tất cả những gì bạn có thể làm tại thời điểm đó là đưa người dùng đến trang lỗi chung. Sẽ tốt hơn nếu quản lý giao dịch trên trang để bạn có thể nắm bắt và xử lý lỗi hiệu quả hơn. Nếu bạn đi theo lộ trình này thì bạn cần truy cập ISession hoặc một trình bao bọc để kiểm soát giao dịch.

Ngoài ra, tại một số thời điểm, ứng dụng của bạn có thể sẽ cần phải sử dụng các thuộc tính hoặc phương pháp được hiển thị bởi ISession, đặc biệt là Hợp nhất và Tải.

+0

Bạn sẽ đề xuất gì thay vì phiên cho mỗi mẫu yêu cầu? Hay bạn đang đề xuất không mở một phiên giao dịch và giao dịch khi ăn xin và sau đó đóng chúng vào cuối yêu cầu? – RandomWebGuy

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