2012-07-06 10 views
8

Estoy empezando a construir una aplicación, y estoy planeando usar ServiceStack. Solo quiero saber cuáles son las mejores prácticas/buenos enfoques para manejar NHibernate ISession u otros objetos de sesión específicos del contexto "por solicitud".ServiceStack NHibernate Sesión por solicitud

pensé registrar un ISessionFactory en el COI como:

container.Register<ISessionFactory>(sessionFactory); 

Y cuando es necesario obtener un nuevo objeto Session ... O tal vez proporcionan el objeto de sesión directamente:

container.Register<ISession>(c => sessionFactory.OpenSession()).ReusedWithin(ReuseScope.None); 

O bien manejar la ISession y una transacción predeterminada a través del evento Global.asax BeginRequest:

protected void Application_BeginRequest(object sender, EventArgs e) 
{ 
    var session = factory.OpenSession(); 
    ITransaction itrans = session.BeginTransaction(); 
    Context.Items.Add("session", session); 
    Context.Items.Add("trans", itrans); 
} 

Entonces, estoy algo perdido, ¿cuáles son las mejores prácticas, dadas las tecnologías anteriores, o similares, como EF u otro marco de servicios de descanso?

Gracias de antemano

Respuesta

3

Ver esta entrada del blog de un ejemplo completo de cómo utilizar de manera óptima ServiceStack y NHibernate juntos:

http://www.philliphaydon.com/2012/06/using-nhibernate-with-servicestack/ Aquí está el ejemplo apphost utilizado en el post anterior:

public class Global : HttpApplication 
{ 
    public class SampleServiceAppHost : AppHostBase 
    { 
     private readonly IContainerAdapter _containerAdapter; 
     public SampleServiceAppHost(ISessionFactory sessionFactory) 
      : base("Service Stack with Fluent NHibernate Sample", typeof(ProductFindService).Assembly) 
     { 
      base.Container.Register<ISessionFactory>(sessionFactory); 
     } 

     public override void Configure(Funq.Container container) 
     { 
      container.Adapter = _containerAdapter; 
     } 
    } 

    void Application_Start(object sender, EventArgs e) 
    { 
     var factory = new SessionFactoryManager().CreateSessionFactory(); 

     (new SampleServiceAppHost(factory)).Init(); 
    } 
} 
4

Crear una sesión por solicitud utilizando un HttpHandler es la forma más común de hacerlo que he encontrado. Ayende ha explicado que crear una sesión es realmente liviano. http://ayende.com/blog/4123/what-is-the-cost-of-opening-a-session

Ayende en realidad tiene series de publicaciones en las que construye gradualmente la solución de acceso a datos. Cada publicación explica por qué hizo lo que hizo y qué problemas deben resolverse con los pasos dados hasta ahora. Haga clic aquí: http://ayende.com/blog/4803/refactoring-toward-frictionless-odorless-code-the-baseline

Por último, http://nhforge.org/blogs/nhibernate/archive/2011/03/03/effective-nhibernate-session-management-for-web-apps.aspx

Todo lo anterior son variaciones de sesión por encargo. Lo común a todos es no tener que preocuparse manualmente por la creación de una sesión/transacción. Ellos confirmarán/revertirán las transacciones automáticamente.

3

Sé que esta es una vieja pregunta, pero pensé que seguiría y mostraría a cualquiera que todavía esté interesado en una respuesta alternativa cómo lo hicimos.

Estamos utilizando el ServiceRunner en la nueva API ServiceStack así:

public class BaseServiceRunner<TRequest> : ServiceRunner<TRequest> 
{ 
    public BaseServiceRunner(AppHost appHost, ActionContext actionContext) 
    : base(appHost, actionContext) { } 

    public override void OnBeforeExecute(IRequestContext requestContext, TRequest request) 
    { 
     var req = request as MyRequestType; 

     if(req == null) 
      base.OnBeforeExecute(requestContext, request); 

     var factory = TryResolve<NHibernate.ISessionFactory>(); 
     var session = factory.OpenSession(); 
     var trans = session.BeginTransaction(IsolationLevel.ReadCommitted); 

     requestContext.SetItem("session", session); 
     requestContext.SetItem("transaction", trans); 
    }   

    public override object OnAfterExecute(IRequestContext requestContext, object response) 
    { 
     var trans = requestContext.GetItem("transaction") as ITransaction; 
     if (trans != null && trans.IsActive) 
      trans.Commit(); 

     var session = requestContext.GetItem("session") as ISession; 
     if (session != null) 
     { 
      session.Flush(); 
      session.Close(); 
     } 

     return base.OnAfterExecute(requestContext, response); 
    } 

    public override object HandleException(IRequestContext requestContext, TRequest request, Exception ex) 
    { 
     var req = request as MyRequestType; 
     if(req != null) 
     { 
      var trans = requestContext.GetItem("transaction") as ITransaction; 
      if (trans != null && trans.IsActive) 
       trans.Rollback(); 

      var session = requestContext.GetItem("session") as ISession; 
      if (session != null) 
      { 
       session.Flush(); 
       session.Close(); 
      } 
     } 
     return base.HandleException(requestContext, request, ex); 
    }   
} 
+1

¿Puede usted explicar con más detalle cómo se utiliza esto? La documentación de ServiceStack realmente no tiene sentido sobre cómo usar estos ServiceRunners. – slashp

+0

Agregué el código para agregar en el host de su aplicación. No estoy seguro de cómo usar el corredor de servicio del servicio. –

+0

Acabo de ver las solicitudes de más detalles, podría ser demasiado tarde para ser útil, pero tal vez otra persona quiera saber. 'código' clase pública AppHost: AppHostBase { public AppHost(): base (" Servicio ", typeof (AccessService).Asamblea) {} override public void Configurar (contenedor de contenedores) {} public override IServiceRunner CreateServiceRunner (ActionContext ActionContext) {return new BaseServiceRunner (esto, ActionContext); } 'código ' –

Cuestiones relacionadas