Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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 ?

share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

There are multiple options that might be used in your case.

One option is described as passing controllers an instance of a NHibernate session which is unique for the HTTP request - NHibernate sessions in ASP.NET MVC

Another options can be found in NHibernate Wiki

share|improve this answer
add comment
  • I am not sure if this is the recommended way to insert the session into the controller — Use constructor injection, as long as session is required for controller. Your "composition root" should be able to do this. And you had provided an example.

  • 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 — usually DI containers are configured with "scope" abstraction. There are several default scopes for most of DI containers, among them are Signleton, Transient, Thread and Request (for HTTP requests). Last one will create one instance of dependency per HTTP request, and injects it into all objects that handle this request. As soon as HTTP Request will be done, DI should dispose all dependencies also. So, there is no need to explicitely create, handle and dispose session yourself.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.