Pregunta

Estoy empezando un nuevo proyecto con NHibernate 3 y estoy tratando de utilizar la API de CurrentSessionContext con WebSessionContext para gestionar mi objetivo ISession.

En proyectos anteriores siempre logró que yo así que cada vez que necesitaba un ISession objeto que me gustaría crear y almacenar en HttpContext.Items colección. Bastante sencillo, pero usando una solución nativa (CurrentSessionContext) parece una mejor opción para este nuevo proyecto.

Cuando he conseguido el objeto que era capaz de hacer una inicialización perezosa en él, lo que significa que sólo me abra una sesión cuando lo necesitaba y no en todas las solicitudes porque no se necesiten y estaría desperdiciando recursos / tiempo abriendo todo el tiempo.

¿Hay una manera simple de hacer que con la API CurrentSessionContext?

Este es el código que estoy usando en el HttpModule responsable de esto:


public class ContextualSessionModule : IHttpModule
{

    public void Init(HttpApplication context)
    {
        context.BeginRequest += context_BeginRequest;
        context.EndRequest += context_EndRequest;
    }

    public void Dispose()
    {
    }

    private static void context_BeginRequest(object sender, EventArgs e)
    {
        var application = (HttpApplication)sender;
        var context = application.Context;

        BindSession(context);
    }

    private static void BindSession(HttpContext context)
    {
        // Create a new session (it's the beginning of the request)
        var session = SessionBuilderFactory.CurrentSessionFactory.OpenSession();

        // Tell NH session context to use it
        CurrentSessionContext.Bind(session);
    }

    private static void context_EndRequest(object sender, EventArgs e)
    {
        var application = (HttpApplication)sender;
        var context = application.Context;

        UnbindSession(context);
    }

    private static void UnbindSession(HttpContext context)
    {
        // Get the default NH session factory
        var factory = SessionBuilderFactory.CurrentSessionFactory;

        // Give it to NH so it can pull the right session
        var session = CurrentSessionContext.Unbind(factory);

        if (session == null) return;
        session.Flush();
        session.Close();
    }
}

Editar

Diego más o menos en el clavo, pero pensé un poco más sobre esto y me recordó la razón principal por la que he implementado el control de mí mismo:. Transacciones

Soy un href="http://jeffreypalermo.com/blog/the-onion-architecture-part-1/" rel="nofollow"> arquitectura de cebolla chico así que mis objetos de dominio (que son los que saben cuándo iniciar una transacción) no tiene acceso a la infraestructura para que no puedan iniciar las transacciones.

Para resolver esto, yo uso la inicialización perezosa y siempre se inicia una transacción al abrir una sesión. Cometer sucede cuando termina la solicitud y no hay excepciones fueron capturados. Además de esto, existe el consejo de Ayende a utilizar siempre las transacciones, incluso cuando se consulta. ¿Alguna idea?

¿Fue útil?

Solución

Si bien no es directamente responder a su pregunta, creo que:? ¿Por qué

Una sesión es un objeto ligero. Si no lo utiliza, sólo se inicializa algunas estructuras internas, pero no se abre una conexión de base de datos o cualquier cosa.

Hay algunos ejemplos en todo (solo Google) para sesiones de apertura evitar para objetos estáticos con el fin de ahorrar un poco de tiempo / memoria. Aparte de eso, puede que no sea digno de él, a menos que sus programas de perfilado que está perjudicando su rendimiento.

Actualización:. Para las necesidades de transacción, echar un vistazo a la implementación CPBT en uNhAddIns

scroll top