2010-09-09 67 views
6

Tôi muốn sử dụng các phiên bối cảnh của NHibernate trong ứng dụng ASP.NET MVC 2 của tôi, nhưng tôi đang gặp khó khăn trong việc tìm kiếm hướng dẫn về cách thực hiện đúng cách này.NHibernate Các phiên bối cảnh trong ASP.NET MVC

Tôi quan tâm đến Phiên cho mỗi yêu cầu.

Trả lời

-1

http://www.sharparchitecture.net

Bạn có thể học thực hiện từ wiki và các nguồn đó, và cũng từ here. Thêm một chút chi tiết của S # arp here, bao gồm cả giải thích về quản lý phiên.

+0

Tôi không nhận thấy rằng bạn cần ICurrentSessionContext, nghĩ rằng bất kỳ "phiên cho mỗi yêu cầu" là OK. – queen3

1

Vui lòng cho tôi biết nếu tôi đang làm điều này đúng cách. Dưới đây là những gì tôi đã đưa ra:

Global.asax

public class MvcApplication : NinjectHttpApplication 
{ 
    public MvcApplication() 
    { 
     NHibernateProfiler.Initialize(); 
     EndRequest += delegate { NHibernateHelper.EndContextSession(Kernel.Get<ISessionFactory>()); };    
    } 

    public static void RegisterRoutes(RouteCollection routes) 
    { 
     routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 
     routes.IgnoreRoute("favicon.ico"); 

     routes.MapRoute(
      "Default", // Route name 
      "{controller}/{action}/{id}", // URL with parameters 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
      ); 
    } 

    protected override void OnApplicationStarted() 
    { 
     AreaRegistration.RegisterAllAreas(); 
     RegisterRoutes(RouteTable.Routes); 
    } 

    protected override IKernel CreateKernel() 
    { 
     StandardKernel kernel = new StandardKernel(); 
     kernel.Load(AppDomain.CurrentDomain.GetAssemblies());    
     return kernel; 
    } 
} 

NHibernateHelper

public class NHibernateHelper 
{ 
    public static ISessionFactory CreateSessionFactory() 
    { 
     var nhConfig = new Configuration(); 
     nhConfig.Configure(); 

     return Fluently.Configure(nhConfig) 
      .Mappings(m => 
       m.FluentMappings.AddFromAssemblyOf<Reservation>() 
       .Conventions.Add(ForeignKey.EndsWith("Id"))) 
#if DEBUG 
      .ExposeConfiguration(cfg => 
      { 
       new SchemaExport(cfg) 
        .SetOutputFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "schema.sql")) 
        .Create(true, false); 
      }) 
#endif 
      .BuildSessionFactory(); 
    } 


    public static ISession GetSession(ISessionFactory sessionFactory) 
    { 
     ISession session; 
     if (CurrentSessionContext.HasBind(sessionFactory)) 
     { 
      session = sessionFactory.GetCurrentSession(); 
     } 
     else 
     { 
      session = sessionFactory.OpenSession(); 
      CurrentSessionContext.Bind(session); 
     } 
     return session; 
    } 

    public static void EndContextSession(ISessionFactory sessionFactory) 
    { 
     var session = CurrentSessionContext.Unbind(sessionFactory); 
     if (session != null && session.IsOpen) 
     { 
      try 
      { 
       if (session.Transaction != null && session.Transaction.IsActive) 
       { 
        // an unhandled exception has occurred and no db commit should be made 
        session.Transaction.Rollback(); 
       } 
      } 
      finally 
      { 
       session.Dispose(); 
      } 
     } 
    } 
} 

NHibernateModule

public class NHibernateModule : NinjectModule 
{ 
    public override void Load() 
    { 
     Bind<ISessionFactory>().ToMethod(x => NHibernateHelper.CreateSessionFactory()).InSingletonScope(); 
     Bind<ISession>().ToMethod(x => NHibernateHelper.GetSession(Kernel.Get<ISessionFactory>())); 
    } 
} 
+0

Ví dụ rất rõ ràng +1 –

1

Chúng ta làm chúng ta hơi khác với bigglesby, và tôi không nói rằng anh ta sai, hay rằng chúng ta là hoàn hảo.

Trong global.asax chúng ta có trên đầu ứng dụng chúng ta có:

... 
protected void Application_Start() { 
    ISessionFactory sf = 
     DataRepository 
      .CreateSessionFactory(
       ConfigurationManager 
        .ConnectionStrings["conn_string"] 
        .ConnectionString 
      ); 

//use windsor castle to inject the session 
ControllerBuilder 
    .Current 
    .SetControllerFactory(new WindsorControllerFactory(sf)); 
} 
... 

DataRepository của chúng tôi, chúng tôi có: GHI CHÚ: (nó không phải là một kho lưu trữ - Lỗi thiết kế của tôi: tên xấu -, nó giống như NHibernateHelper của bạn, tôi đoán nhiều hơn của một wrapper cấu hình NH của một số loại ...)

.... 
public static ISessionFactory CreateSessionFactory(string connectionString) { 
    if (_sessionFactory == null){ 
    _sessionFactory = Fluently.Configure() 
       .Database(MsSqlConfiguration ... 
        ... 
        //custom configuration settings 
        ... 
        cfg.SetListener(ListenerType.PostInsert, new AuditListener()); 
       }) 
       .BuildSessionFactory(); 
    } 
    return _sessionFactory; 
} 
.... 

Điều với nhà máy phiên, là bạn không muốn tạo/xây dựng một trên mỗi yêu cầu. DataRepository hoạt động như một singleton, đảm bảo rằng nhà máy phiên chỉ được tạo một lần, và đó là khi ứng dụng khởi động. Trong bộ điều khiển cơ sở của chúng ta, chúng ta tiêm phiên làm việc hoặc sessionfactory vào bộ điều khiển của chúng ta (Một số bộ điều khiển không yêu cầu kết nối cơ sở dữ liệu, do đó chúng lấy từ bộ điều khiển cơ sở "cơ sở dữ liệu"), sử dụng WindosrCastle. WindsorControllerFactory, chúng ta có:

... 
//constructor 
public WindsorControllerFactory(ISessessionFactory) { 
    Initialize(); 

    // Set the session Factory for NHibernate 
    _container.Register(
    Component.For<ISessionFactory>() 
      .UsingFactoryMethod(
       () => sessionFactory) 
        .LifeStyle 
        .Transient 
      ); 
} 

private void Initialize() { 
    _container = new WindsorContainer(
        new XmlInterpreter(
         new ConfigResource("castle") 
        ) 
       ); 
    _container.AddFacility<FactorySupportFacility>(); 

    // Also register all the controller types as transient 
    var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes() 
         where typeof(IController).IsAssignableFrom(t) 
         select t; 

    foreach (var t in controllerTypes) { 
     _container.AddComponentLifeStyle(t.FullName, t, LifestyleType.Transient); 
    } 
} 
.... 

Với điều này thiết lập, Mỗi yêu cầu tạo ra một phiên NHibernate, và với thiết kế của chúng tôi, chúng tôi cũng có thể có điều khiển mà không tạo ra phiên. Và đó là cách nó hoạt động cho chúng ta.

Tôi cũng có thể nói rằng tôi đã tìm thấy NHProf rất hữu ích khi cố gắng định cấu hình hoặc gỡ lỗi sự cố mà chúng tôi đã gặp phải.

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