Search code examples
asp.net-mvc-3unity-containerninject-2

ASP.Net MVC 3 project with Ninject and HierarchicalLifetimeManager?


First of all, dependency injection is relatively new to me. I did a first project using Unity.MVC3, and now I would like to switch to Ninject on a new project, since it seems to be the most popular dependency injector for .Net projects. So now, I am trying to use Ninject v2.2.1.4 with Ninject.MVC3 v2.2.2.0 in my project.

In my previous project where I was using Unity, I had something like the following code in my Bootstrapper class:

private static IUnityContainer BuildUnityContainer()
{
    var container = new UnityContainer();

    container.RegisterType<ITestService, TestService>();            
    container.RegisterType<IDatabaseFactory, DatabaseFactory>(new HierarchicalLifetimeManager());
    container.RegisterType<IUnitOfWork, UnitOfWork>();
    container.RegisterType<ILoggingService, LoggingService>();

    container.RegisterControllers();

    return container;
}

Now, I my new project, I replaced this with something like the following code in the NinjectMVC3 class (App_Start):

private static void RegisterServices(IKernel kernel)
{
    kernel.Bind<ITestService>().To<TestService>();
    //This does not compile:
    //kernel.Bind<IDatabaseFactory>().To<DatabaseFactory>(new HierarchicalLifetimeManager());
    kernel.Bind<IDatabaseFactory>().To<DatabaseFactory>();
    kernel.Bind<IUnitOfWork>().To<UnitOfWork>();
    kernel.Bind<ILoggingService>().To<LoggingService>();
} 

However, I don't know what I should do with the DatabaseFactory binding, since it normally requires the use of HierarchicalLifetimeManager. Can anyone tell me how to properly create the binding for DatabaseFactory?


Solution

  • First of all, add these references bu NuGet to be sure that you have a compatible set of packages.

    Then, if you add the Ninject.Web.MVC it will setup the project initialization code for you through a power shell script.

    And last make a BindModule class like this and add it to module in CreateKernel method that have been created in second step.

    public class BindModule : NinjectModule
    {
        public override void Load()
        {
            this.Bind<IControllerActivator>().To<CustomControllerActivator>().InRequestScope();
            this.Bind<MembaseClient>().ToMethod(context => new MembaseClient()).InSingletonScope();
            this.Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
            this.Bind<ISessionFactory>().ToMethod(o => MyAutoMapper.sessionFactory).InSingletonScope();
            this.Bind<ISession>().ToMethod(o => MyAutoMapper.sessionFactory.OpenSession()).InRequestScope();
            }
      }
    

    Part of NinjectMVC3 class

    public static class NinjectMVC3
    {
        /// <summary>
        /// Creates the kernel that will manage your application.
        /// </summary>
        /// <returns>The created kernel.</returns>
        private static IKernel CreateKernel()
        {
            var modules = new NinjectModule[] { new BindModule() };
            var kernel = new StandardKernel(modules);
    
            RegisterServices(kernel);
    
            return kernel;
        }
    }
    

    As you can see above Ninjet has built in functions to take care of different life cycles for each object.