2010-09-09 18 views

Respuesta

-1

http://www.sharparchitecture.net

Usted puede aprender implementación de wiki y las fuentes allí, y también de here. Un poco más de detalles de S # arp here, incluida la explicación de gestión de sesiones.

+0

No noté que necesita ICurrentSessionContext, pensó que cualquier "sesión por solicitud" está bien. – queen3

1

Háganme saber si lo estoy haciendo bien. Esto es lo que ocurrió:

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

Ejemplo muy limpio +1 –

1

Hacemos las nuestras de una manera ligeramente diferente a bigglesby, y no estoy diciendo que la suya sea incorrecta, o que la nuestra sea perfecta.

En el Global.asax tenemos al iniciar la aplicación tenemos:

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

Nuestra DataRepository tenemos: NOTA: (No es un repositorio - mi error de diseño: mal nombre -, es más como su NHibernateHelper, supongo que es más de un envoltorio de configuración NH de algún tipo ...)

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

la cosa con la fábrica de sesiones, es que usted no desea generar/construir uno en cada petición. El DataRepository actúa como un singleton, asegurando que la fábrica de sesiones solo se crea una vez, y eso es en el inicio de la aplicación. En nuestro controlador base, inyectamos la sesión o la sesión en nuestros controladores (algunos controladores no requieren una conexión de base de datos, por lo que derivan de un controlador base "sin base de datos"), utilizando WindosrCastle. Nuestra WindsorControllerFactory tenemos:

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

Con esta configuración, cada solicitud genera una sesión de NHibernate, y con nuestro diseño también somos capaces de tener los controladores que no generan sesiones. Y así es como funciona actualmente para nosotros.

También puedo decir que he encontrado NHProf muy útil al intentar configurar o solucionar problemas que hemos tenido.

Cuestiones relacionadas