MVC5 and WebAPI configuration causes HelpController Error

Oct 22, 2013 at 7:57 PM
G'day,
I am working on my first Simple Injector project, so my issue/question may be a PEBKAC. I'm having troubles configuring a new VS 2013 MVC5 + Web Api integrated solution and setting up the DI for both without triggering an exception. Would someone please put me out of my misery and point out what I've done wrong?

The configuration is invalid. Creating the instance for type HelpController failed. The registered delegate for type HelpController threw an exception. For the container to be able to create HelpController, it should contain exactly one public constructor, but it has 2.

I've been working with a series of code snippits from
StackOverflow
Simple Injection docs - MVC integration
Simple Injection docs - WebApi integration
Working with Multiple Injectors
HttpConfiguration

Now it's obviously the httpConfiguration multiple constructors that's triggering the problem and a pattern considered an "anti pattern" from Simple Injectors perspective. What is the method for forcing empty constructors 'redirect' to the constructor with parameters via Simple Injector?
[assembly: WebActivator.PostApplicationStartMethod(typeof(JDManufacturing.App_Start.SimpleInjectorInitializer), "Initialize")]
namespace JDManufacturing.App_Start
{
    using System;
    using System.Linq;
    using System.Reflection;
    using System.Web.Mvc;
    using System.Web.Http;
    using System.Web.Http.Controllers;
    
    //  Custom Business Logic    
    using Operations.Library.Repositories;
        
    //  IOC Framework
    using SimpleInjector;
    using SimpleInjector.Extensions;
    using SimpleInjector.Integration.Web.Mvc;

    /// <summary>
    /// Logic for IOC dependancy Injection.
    /// </summary>
    public static class SimpleInjectorInitializer
    {
        /// <summary>Initialize the container and register it as MVC Dependency Resolver.</summary>
        public static void Initialize()
        {
            // Create the container as usual.
            var container = new Container();

            // register Web API controllers (important! http://bit.ly/1aMbBW0)
            var services = GlobalConfiguration.Configuration.Services;
            var controllerTypes = services.GetHttpControllerTypeResolver().GetControllerTypes(services.GetAssembliesResolver());

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

            // Register all the software applications Dependancy Resolver components.
            ConfigureMyDIComponents(container);

            // This is an extension method from the integration package.
            container.RegisterMvcControllers(Assembly.GetExecutingAssembly()); //   HelpController - Failurepoint

            // This is an extension method from the integration package as well.
            container.RegisterMvcAttributeFilterProvider(); //   HelpController - Failurepoint


            // Verify the container configuration
            container.Verify(); //  HelpController - can not verify correctly, making the Web API pages error.

            //  Register the MVC dependency Resolver
            DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));

            // Register the web API dependency resolver.
            GlobalConfiguration.Configuration.DependencyResolver =
                new SimpleInjectorWebApiDependencyResolver(container);
            
            //DependencyResolver.Current.GetService<InterfaceName>();
        }
     
        /// <summary>
        /// 
        /// </summary>
        /// <param name="container"></param>
        private static void ConfigureMyDIComponents(Container container)
        {

            //  TODO:   Register all the Interfaces that will be resolved with concrete implementations
            //  TODO:   Provide a mechanism to swap between Fake repositories and various repository implementations. 
            //          Use the repository pattern to provide multiple data sourcesAWSDynamoDB, AWSSimpleDB, AzureSQL, AzureTable, MSSQL, SQLLite
            container.Register<IRepositoryForRegisters, Operations.Fake.IRepositoryForRegistersImplementer>();
        }
    }
}
Coordinator
Oct 22, 2013 at 8:30 PM
The HelpController is part of the Web API template for Visual Studio 2012 and 2013. You are free to change the code that is generated. For instance, you can remove on of the constructors, make the overloaded constructor protected, or even completely remove the HelpController. There are multiple ways to register types with multiple public constructors, such as overriding the constructor resolution behavior, or simply by overriding the made registration with a delegate registration. But if you can, remove the ambiguity from your design.
Marked as answer by dot_NET_Junkie on 2/26/2014 at 1:16 PM
Nov 21, 2013 at 5:19 AM
Thanks for the option. In the end I wanted MVC + WebAPI in one project (for the time being), so I modified the HelpController to remove the HttpConfiguration constructor. The resulting HelpController code now looks like the following:-
/// <summary>
    /// The controller that will handle requests for the help page.
    /// </summary>
    /// <remarks>Modified to work with IOC. The Microsoft supplied constructor included a reference to httpConfiguration in a constructor that was difficult to implement with SimpleInjector single constructor approach. As there is a perfectly good GlobalConfiguration.Configuration static property available in a MVC + WebAPI solution, we just use it.</remarks>
    public class HelpController : Controller
    {
      
        public ActionResult Index()
        {
            ViewBag.DocumentationProvider = GlobalConfiguration.Configuration.Services.GetDocumentationProvider();
            return View(GlobalConfiguration.Configuration.Services.GetApiExplorer().ApiDescriptions);
        }

        public ActionResult Api(string apiId)
        {
            if (!String.IsNullOrEmpty(apiId))
            {

                HelpPageApiModel apiModel = GlobalConfiguration.Configuration.GetHelpPageApiModel(apiId);
                if (apiModel != null)
                {
                    return View(apiModel);
                }
            }

            return View("Error");
        }
    }