This project is read-only.

QuickStart example for NHibernate, MVC 5 and WebAPI

Mar 4, 2014 at 2:39 PM
Hi,

Being new to Simple Injector wondering if anyone has used it with NHibernate, MVC 5 and WebAPI 2 in a project, and if there is a QuickStart or article on how to do this?

Thanks,
TB
Mar 4, 2014 at 2:56 PM
The integration guide has examples for both MVC and Web API and there are quick start NuGet packages for both MVC and Web API, so that would get you going rather quickly with those technologies.

There's however now information in the wiki about NHibernate integration, but if you have any specific questions about this, I'm happy to answer this. The integration guide point at this stackoverflow q/a, which talks about registering your ISession on a per-request basis. It might give you some ideas.

Cheers
Mar 5, 2014 at 3:54 AM
I created an empty MVC 5 project, then ran the various nuget packages which resulted in the following assembly references:

<package id="SimpleInjector" version="2.5.0" targetFramework="net45" />
<package id="SimpleInjector.Extensions.ExecutionContextScoping" version="2.5.0" targetFramework="net45" />
<package id="SimpleInjector.Integration.Web" version="2.5.0" targetFramework="net45" />
<package id="SimpleInjector.Integration.Web.Mvc" version="2.5.0" targetFramework="net45" />
<package id="SimpleInjector.Integration.WebApi" version="2.5.0" targetFramework="net45" />
<package id="SimpleInjector.Integration.WebApi.WebHost.QuickStart" version="2.5.0" targetFramework="net45" />
<package id="SimpleInjector.MVC3" version="2.5.0" targetFramework="net45" />

I also noticed a single file was created in App_Start called SimpleInjectorWebApiInitializer.cs
        public static void Initialize()
        {
            // Did you know the container can diagnose your configuration? Go to: https://bit.ly/YE8OJj.
            var container = new Container();
            
            InitializeContainer(container);

            container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
       
            container.Verify();
            
            GlobalConfiguration.Configuration.DependencyResolver =
                new SimpleInjectorWebApiDependencyResolver(container);
        }
Should there have been any other files created? Also being new to NH I came across an Autofac example and assume I need to do something similar in Simple Injector to the following:
builder.Register(context => NhibernateConfig.GetSessionFactory()).As<ISessionFactory>().SingleInstance();
            
// Use a session per web request.
builder.Register(context => context.Resolve<ISessionFactory>().OpenSession()).As<ISession>().InstancePerHttpRequest();
From reading various Nhibernate blogs it seems it's best to lazy load a single Nhibernate Session per web request, opening the session only when actually needed.

PS. Appreciate any assistance as I work my way through Simple Injector, Nhibernate and MVC 5 setup....
Mar 5, 2014 at 6:51 AM
Edited Apr 15, 2014 at 9:56 AM
If you install the SimpleInjector.MVC3 package, you'll get a SimpleInjectorInitializer.cs for MVC as well. This bootstraps your MVC application, which basically means registering the DependencyResolver for MVC. Do note that both the Initializer.cs files will create their own container, but you should usually have only one container instance per app domain.

But think twice before you mix MVC and Web API into the same project. I think it is best to split MVC and Web API. I advice you toread this and this for more information.

About the NHibernate configuration, this would be the Simple Injector equivalent:
container.RegisterSingle<ISessionFactory>(() => NhibernateConfig.GetSessionFactory());
container.RegisterPerWebRequest<ISession>(() => container.GetInstance<ISessionFactory>().OpenSession());

// Or this for Web API
container.RegisterSingle<ISessionFactory>(() => NhibernateConfig.GetSessionFactory());
container.RegisterWebApiRequest<ISession>(() => container.GetInstance<ISessionFactory>().OpenSession());

// Or when you mix Web API and MVC in the same project
// using SimpleInjector.Extensions.ExecutionContextScoping (namespace)
var hybrid = Lifestyle.CreateHybrid(
    () => container.GetCurrentExecutionContextScope() != null,
    new WebApiRequestLifestyle(),
    new WebRequestLifestyle());

container.RegisterSingle<ISessionFactory>(() => NhibernateConfig.GetSessionFactory());
container.Register<ISession>(() => container.GetInstance<ISessionFactory>().OpenSession(), hybrid);
Instead of doing a resolve inside the registration however, I think it's cleaner to do the following registration:
var factory =  NhibernateConfig.GetSessionFactory();

container.RegisterPerWebRequest<ISession>(() => factory.OpenSession());
Marked as answer by dot_NET_Junkie on 4/15/2014 at 1:56 AM