2010-09-09 5 views

Répondre

-1

http://www.sharparchitecture.net

Vous pouvez apprendre la mise en œuvre du wiki et les sources là-bas, et aussi de here. Un peu plus de S # arp détails here, y compris l'explication de gestion de session.

+0

Je n'ai pas remarqué que vous avez besoin de ICurrentSessionContext, je pense que toute "session par requête" est OK. – queen3

1

S'il vous plaît laissez-moi savoir si je le fais de la bonne façon. Voici ce que je suis venu avec:

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

Exemple très propre +1 –

1

Nous faisons le nôtre un peu différemment de bigglesby, et je ne dis pas que c'est faux, ou que le nôtre est parfait.

Dans le global.asax, nous avons le démarrage de l'application, nous avons:

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

Notre DataRepository nous avons: NOTE: (il n'est pas un dépôt - mon erreur de conception: mauvais nom -, son plus comme votre NHibernateHelper, je suppose que son plus d'une enveloppe de configuration NH de quelque sorte ...)

.... 
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 chose avec l'usine de session, est que vous ne souhaitez pas générer/construire un à chaque demande. Le DataRepository agit comme un singleton, en s'assurant que la fabrique de sessions n'est créée qu'une seule fois, et c'est au démarrage de l'application. Dans notre contrôleur de base, nous injectons soit la session, soit la sessionfactory dans nos contrôleurs (Certains contrôleurs ne nécessitent pas de connexion à une base de données, donc ils dérivent d'un contrôleur de base "sans base de données"), en utilisant WindosrCastle. Notre WindsorControllerFactory nous avons:

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

Avec cette configuration, chaque demande génère une session NHibernate, et avec notre conception, nous sommes également en mesure d'avoir des contrôleurs qui ne génèrent pas de sessions. Et c'est actuellement comment cela fonctionne pour nous. Puis-je également dire que j'ai trouvé NHProf très utile lorsque vous essayez de configurer ou de déboguer le problème que nous avons eu.