Quali sono le migliori pratiche per utilizzare le sessioni di NHibernate in asp.net (mvc / web api)?

2

Ho la seguente configurazione nel mio progetto:

public class WebApiApplication : System.Web.HttpApplication
{
    public static ISessionFactory SessionFactory { get; private set; }

    public WebApiApplication()
    {
        this.BeginRequest += delegate
        {
            var session = SessionFactory.OpenSession();
            CurrentSessionContext.Bind(session);
        };


        this.EndRequest += delegate
        {
            var session = SessionFactory.GetCurrentSession();

            if (session == null)
            {
                return;
            }

            session = CurrentSessionContext.Unbind(SessionFactory);
            session.Dispose();
        };
    }

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        var assembly = Assembly.GetCallingAssembly();
        SessionFactory = new NHibernateHelper(assembly, Server.MapPath("/")).SessionFactory;
    }
}

public class PositionsController : ApiController
{
    private readonly ISession session;

    public PositionsController()
    {
        this.session = WebApiApplication.SessionFactory.GetCurrentSession();
    }

    public IEnumerable<Position> Get()
    {
        var result = this.session.Query<Position>().Cacheable().ToList();

        if (!result.Any())
        {
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
        }

        return result;
    }

    public HttpResponseMessage Post(PositionDataTransfer dto)
    {
        //TODO: Map dto to model
        IEnumerable<Position> positions = null;
        using (var transaction = this.session.BeginTransaction())
        {
            this.session.SaveOrUpdate(positions);

            try
            {
                transaction.Commit();
            }
            catch (StaleObjectStateException)
            {
                if (transaction != null && transaction.IsActive)
                {
                    transaction.Rollback();
                }
            }
        }

        var response = this.Request.CreateResponse(HttpStatusCode.Created, dto);
        response.Headers.Location = new Uri(this.Request.RequestUri.AbsoluteUri + "/" + dto.Name);
        return response;
    }

    public void Put(int id, string value)
    {
        //TODO: Implement PUT
        throw new NotImplementedException();
    }

    public void Delete(int id)
    {
        //TODO: Implement DELETE
        throw new NotImplementedException();
    }
}

Non sono sicuro se questo è il modo consigliato per inserire la sessione nel controller. Stavo pensando di usare DI ma non sono sicuro di come iniettare la sessione che viene aperta e associata nel delegato BeginRequest nel costruttore di Controllers per ottenere questo

    public PositionsController(ISession session)
    {
        this.session = session;
    }

Domanda: Qual è il modo consigliato di utilizzare le sessioni di NHibernate in asp.net mvc / web api?

    
posta mrt181 04.07.2012 - 14:04
fonte

2 risposte

2

Ci sono più opzioni che potrebbero essere utilizzate nel tuo caso.

Un'opzione è descritta come controllori che passano un'istanza di una sessione di NHibernate che è unica per la richiesta HTTP - Sessioni di NHibernate in ASP.NET MVC

Un'altra opzione può essere trovata in Wiki NHibernate

    
risposta data 04.07.2012 - 15:15
fonte
2
  • Non sono sicuro che questo sia il modo consigliato di inserire la sessione nel controller - Utilizzare l'iniezione del costruttore, purché sia necessaria la sessione per il controller. La tua "composizione root" dovrebbe essere in grado di farlo. E tu hai fornito un esempio.

  • Stavo pensando di usare DI ma non sono sicuro di come iniettare la sessione che è aperta e legata nel delegato BeginRequest nel costruttore di Controllers per ottenere questo - di solito i contenitori DI sono configurato con l'astrazione "scope". Esistono diversi ambiti predefiniti per la maggior parte dei contenitori DI, tra cui Signleton , Transient , Thread e Request ( per richieste HTTP). L'ultimo creerà un'istanza di dipendenza per ogni richiesta HTTP e la inserirà in tutti gli oggetti che gestiscono questa richiesta. Non appena verrà effettuata la richiesta HTTP, DI dovrebbe disporre anche di tutte le dipendenze. Pertanto, non è necessario creare, gestire ed eliminare la sessione in modo esplicito.

risposta data 04.07.2012 - 14:55
fonte