Simple Injector initialize for both MVC and Web API controllers

FailedUnitTest picture FailedUnitTest · May 31, 2016 · Viewed 9k times · Source

I have a Web API controller that has some resources DI'd. Out of later necessity I have added an MVC controller, now I need same resources DI'd there as well. Here is my original configuration:

    [assembly: WebActivator.PostApplicationStartMethod(typeof(CineplexSearch.App_Start.SimpleInjectorWebApiInitializer), "Initialize")]

namespace CineplexSearch.App_Start
{
    using System.Web.Http;
    using SimpleInjector;
    using SimpleInjector.Integration.WebApi;

    public static class SimpleInjectorWebApiInitializer
    {
        /// <summary>Initialize the container and register it as Web API Dependency Resolver.</summary>
        public static void Initialize()
        {
            var container = new Container();
            container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();

            InitializeContainer(container);

            container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

            container.Verify();

            GlobalConfiguration.Configuration.DependencyResolver =
                new SimpleInjectorWebApiDependencyResolver(container);
        }

        private static void InitializeContainer(Container container)
        {
            container.Register<ICachingManager, CachingManager>(Lifestyle.Transient);
            container.Register<IDataAccessLayer, DataAccessLayer>(Lifestyle.Transient);
        }
    }
}

Can I register DI for MVC Controller in the same place as well? Can I reuse the container?

Update: I must be close, but now I get an error in the Web API controller that I need a parameterless constructor; I tried adding it, but then nothing gets injected of course

public static class SimpleInjectorWebApiInitializer
{
    /// <summary>Initialize the container and register it as Web API Dependency Resolver.</summary>
    public static void Initialize()
    {
        var container = new Container();
        container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

        InitializeContainer(container);

        container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
        container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

        container.Verify();

        //GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
        DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
    }

    private static void InitializeContainer(Container container)
    {
        container.Register<ICachingManager, CachingManager>(Lifestyle.Transient);
        container.Register<IDataAccessLayer, DataAccessLayer>(Lifestyle.Transient);
    }
}

Answer

Steven picture Steven · May 31, 2016

Can I reuse the container?

Yes you can, and you should. Every app domain should typically have one container instance.

The MVC integration documentation of the Simple Injector documentation explains that you should set the MVC DependencyResolver as follows:

DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));

To make things easier however, your should register the WebRequestLifestyle as DefaultScopedLifestyle:

container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

This will work for Web API as well, since you are solely running Web API from within IIS.

So you need to configure both the DependencyResolvers.