What are the best practices to use NHiberante sessions in asp.net (mvc/web api) ?

Posted by mrt181 on Programmers See other posts from Programmers or by mrt181
Published on 2012-07-04T12:04:22Z Indexed on 2012/07/04 15:23 UTC
Read the original article Hit count: 190

I have the following setup in my project:

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

I am not sure if this is the recommended way to insert the session into the controller. I was thinking about using DI but i am not sure how to inject the session that is opened and binded in the BeginRequest delegate into the Controllers constructor to get this

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

Question: What is the recommended way to use NHiberante sessions in asp.net mvc/web api ?

© Programmers or respective owner

Related posts about design-patterns

Related posts about ASP.NET