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 NHibernate sessions in asp.net mvc/web api ?
2 Answers 2
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
-
1The 2nd link is dead.Gert Arnold– Gert Arnold2023年03月29日 15:28:39 +00:00Commented Mar 29, 2023 at 15:28
-
Thank you @GertArnold for pinging back!Yusubov– Yusubov2024年01月26日 16:44:08 +00:00Commented Jan 26, 2024 at 16:44
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.
Explore related questions
See similar questions with these tags.