2010-09-09 12 views

Antwort

-1

http://www.sharparchitecture.net

Sie können dort die Umsetzung von Wiki und Quellen erfahren, und auch von here. Ein bisschen mehr von S # arp Details here, einschließlich Session Management Erklärung.

+0

Ich habe nicht bemerkt, dass Sie ICurrentSessionContext brauchen, dachte jede "Sitzung pro Anfrage" ist in Ordnung. – queen3

1

Bitte lassen Sie mich wissen, wenn ich das richtig mache. Hier ist, was ich kam mit:

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

Sehr sauber Beispiel +1 –

1

Wir machen das etwas anders als Bigglesby, und ich sage nicht, dass er falsch ist oder dass unser perfekt ist.

Im global.asax wir beim Start der Anwendung haben wir haben:

... 
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)); 
} 
... 

Unsere DataRepository haben wir: Hinweis: (es ist nicht ein Repository - mein Design-Fehler: Verruf -, seine eher wie Ihre NHibernateHelper, ich denke, es ist eher ein NH-Konfiguration Wrapper von einer Art ...)

.... 
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; 
} 
.... 

die Sache mit der Session-Fabrik, werden Sie wollen jede Anforderung nicht generieren/bauen eine auf. Das DataRepository fungiert als Singleton und stellt sicher, dass die Sitzungsfactory nur einmal erstellt wird, und zwar beim Start der Anwendung. In unserem Basis-Controller injizieren wir entweder die Sitzung oder die Sessionfactory in unsere Controller (einige Controller benötigen keine Datenbankverbindung, so dass sie von einem "datenbanklosen" Basis-Controller stammen), indem sie WindosrCastle verwenden. Unsere WindsorControllerFactory haben wir:

... 
//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); 
    } 
} 
.... 

Mit dieser Einrichtung, jede Anforderung erzeugt eine NHibernate-Sitzung, und mit unserem Design sind wir auch in der Lage Controller zu haben, die Sitzungen nicht erzeugen. Und genau so funktioniert es für uns.

Kann ich auch sagen, dass ich NHProf sehr nützlich gefunden habe, wenn Sie versuchen, das Problem, das wir hatten, zu konfigurieren oder zu debuggen.