ASP.NET MVC und NHibernate ISession per Request

Written on November 07, 2011

Robert hat vor kurzem "Keep it simple! YAGNI!" mit Bezug auf das Posting "Keep your code simple!" von Daniel Lang gepostet.

Da ich immer mal wieder gefragt wurde, wie man die NHibernate ISession in ASP.NET MVC per Request verwenden kann, hier ein Auszug aus der Global.asax:

public static void RegisterRoutes(RouteCollection routes) {
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new {controller = "Home", action = "Index", id = UrlParameter.Optional}
        );


    ControllerBuilder.Current.SetControllerFactory(
        new LightCore.Integration.Web.Mvc.ControllerFactory(_container));
}

protected void Application_Start() {
    AreaRegistration.RegisterAllAreas();
    setupIoC();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
}

void setupIoC() {
    Action<MappingConfiguration> mappingsConfig =
        mappings => mappings.FluentMappings.AddFromAssemblyOf<ContactMap>();

    var builder = new ContainerBuilder();

    SessionFactory =
        Fluently.Configure().Database(
            MsSqlConfiguration.MsSql2005
                .ConnectionString(
                    connectionString => connectionString
                        .FromConnectionStringWithKey("MvcNHibernate")))
                        .CurrentSessionContext("web") // für ISession per Request
                .Mappings(mappingsConfig).BuildSessionFactory();

    builder.Register<ISession>(c => SessionFactory.GetCurrentSession());

    var container = builder.Build();
}

protected void Application_BeginRequest() {
    CurrentSessionContext.Bind(SessionFactory.OpenSession());
}

protected void Application_EndRequest() {
    CurrentSessionContext.Unbind(SessionFactory);
}

public static ISessionFactory SessionFactory { get; private set; }

Zunächst werden die Mappings gelesen und mittels FluentNHibernate eine SessionFactory erzeugt. Diese wird als Property verfügbar gemacht und in Application_BeginRequest wird eine ISession erzeugt bzw. Application_EndRequest zerstört.

Wenn die ISession innerhalb des Requests (z.B. in einem Controller) benötigt wird, wird sie per IoC-Container (in diesem Fall LightCore) von der SessionFactory angefordert und bereitgestellt.

Der Controller sieht dann wie folgt aus:

public class HomeController : Controller {
    readonly ISession _session;

    public HomeController(ISession session) {
        _session = session;
    }

    public ActionResult Index() {
        ViewBag.Message = "Welcome to ASP.NET MVC!";
        var customers = _session.Query<Customer>();
        return View(customers);
    }

    public ActionResult About() {
        var contacts =_session.Query<Contact>();
        return View(contacts);
    }
}

DotNetKicks-DE Image