Can Simple Injector support Web API and MVC Controllers simultaneously?

May 10, 2013 at 8:32 PM
Edited May 10, 2013 at 8:38 PM
I have an MVC 4 ASP.NET Web API project in which I want to be able to inject a repository into both a MVC controller and an Web API controller. Obviously the project itself supports both types of controllers. I have found documentation on the Simple Injector site which shows how to implement either but not both at once.

I have tried several methods, both of which can be seen in the code below, to no avail:
 public static class SimpleInjectorInitializer
    {
        /// <summary>Initialize the container and register it as MVC3 Dependency Resolver.</summary>
        public static void Initialize()
        {
            var container = new Container();

            // register Web API controllers (important!)
            var controllerTypes =
                from type in Assembly.GetExecutingAssembly().GetExportedTypes()
                where typeof(IHttpController).IsAssignableFrom(type) 
                where !type.IsAbstract
                where !type.IsGenericTypeDefinition
                where type.Name.EndsWith("Controller", StringComparison.Ordinal)
                select type;

            foreach (var controllerType in controllerTypes)
            {
                container.Register(controllerType);
            }

            // Register your types, for instance:
            container.Register<IRepository, Repository>();

            // register MVC controllers (This is an extension method from the integration package).
            container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

            // register MVC controllers - second method (This is an extension method from the integration package).
            //var mvcControllerTypes =
            //    from type in SimpleInjectorMvcExtensions.GetControllerTypesToRegister(container, Assembly.GetExecutingAssembly())
            //    where type.Name != "HelpController"
            //    select type;

            //foreach (Type controllerType in mvcControllerTypes)
            //{
            //    container.Register(controllerType);
            //}

            // register MVC attributes (This is an extension method from the integration package as well).
            container.RegisterMvcAttributeFilterProvider();

            // Verify the container configuration
            container.Verify();

            // Register the dependency resolver.
            GlobalConfiguration.Configuration.DependencyResolver =
                new SimpleInjectorWebApiDependencyResolver(container);
        }
    }
Here is the SimpleInjectorWebApiDependencyResolver calss taken from the Web API guide:
public sealed class SimpleInjectorWebApiDependencyResolver
    : IDependencyResolver
{
    private readonly Container container;

    public SimpleInjectorWebApiDependencyResolver(
        Container container)
    {
        this.container = container;
    }

    [DebuggerStepThrough]
    public IDependencyScope BeginScope()
    {
        return this;
    }

    [DebuggerStepThrough]
    public object GetService(Type serviceType)
    {
        return ((IServiceProvider)this.container)
            .GetService(serviceType);
    }

    [DebuggerStepThrough]
    public IEnumerable<object> GetServices(Type serviceType)
    {
        return this.container.GetAllInstances(serviceType);
    }

    [DebuggerStepThrough]
    public void Dispose()
    {
    }
}
http://simpleinjector.codeplex.com/wikipage?title=Web%20API%20Integration
http://simpleinjector.codeplex.com/wikipage?title=MVC%20Integration
Coordinator
May 11, 2013 at 9:35 AM
Edited Feb 21, 2014 at 1:48 PM
What is exactly the problem you are having?

Although not advised, integrating MVC and Web API in the same project is possible. But since both frameworks have their own API for dependency resolution, you will have to make sure that you register both the MVC DependencyResolver and the Web API DependencyResolver, like this:
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver =
    new SimpleInjectorWebApiDependencyResolver(container);
        
System.Web.Mvc.DependencyResolver.SetResolver(
    new SimpleInjector.Integration.Web.Mvc.SimpleInjectorDependencyResolver(container));
Marked as answer by dot_NET_Junkie on 2/26/2014 at 1:32 PM
May 13, 2013 at 8:17 PM
Thanks! - Adding the additional SetResolver call did the trick! Here is my final code:
  public static class SimpleInjectorInitializer
    {
        /// <summary>Initialize the container and register it as MVC3 Dependency Resolver.</summary>
        public static void Initialize()
        {
            var container = new Container();

            // register Web API controllers (important!)
            var controllerTypes =
                from type in Assembly.GetExecutingAssembly().GetExportedTypes()
                where typeof(IHttpController).IsAssignableFrom(type) // (typeof(IHttpController).IsAssignableFrom(type) || (typeof(IController).IsAssignableFrom(type) && type.Name != "HelpController"))
                where !type.IsAbstract
                where !type.IsGenericTypeDefinition
                where type.Name.EndsWith("Controller", StringComparison.Ordinal)
                select type;

            foreach (var controllerType in controllerTypes)
            {
                container.Register(controllerType);
            }

            // Register your types, for instance:
            container.Register<IRepository, Repository>();

            // register MVC controllers (This is an extension method from the integration package).
            container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

            // register MVC attributes (This is an extension method from the integration package as well).
            container.RegisterMvcAttributeFilterProvider();

            // Verify the container configuration
            container.Verify();

            System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver =
                new SimpleInjectorWebApiDependencyResolver(container);

            System.Web.Mvc.DependencyResolver.SetResolver(
                new SimpleInjector.Integration.Web.Mvc.SimpleInjectorDependencyResolver(container));

        }
    }