Klaus Nji
Klaus Nji

Reputation: 18857

Mixing Unity Web API and MVC4 UnityDependencyResolvers: No parameterless constructor defined for this object

I am getting the following exception:

No parameterless constructor defined for this object.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.MissingMethodException: No parameterless constructor defined for this object.

when the framework attempts to construct controllers that do not derive from ApiController, such as my simple HomeController below:

 public class HomeController : Controller
        {
            private IUnityContainer _unityContainer;
            public HomeController(IUnityContainer unityContainer)
            {
                _unityContainer = unityContainer;
            }
            public ActionResult Index()
            {
                return View();
            }
        }

I have the following Boostrapper.cs class defined:

     public static class Boostrapper
        {
            public static void Initialize()
            {
                var container = BuildUnityContainer();
                GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);                          
            }

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

and Bootstrapper.Initialize() is the last line of code executed within Application_Start of Global.asax.cs?

Exception is not thrown on controller classes that derive from ApiController. Could someone please advise on what I am missing?

Thanks.

Upvotes: 3

Views: 5872

Answers (3)

leeroya
leeroya

Reputation: 491

For me I had

Unity.WebAPI

Already installed and I was using API controllers and decided to create some views for the API, all I needed to do is

install-package Unity.Mvc

and when promoted for the UnityConfig over write I said no as my Interface to Concrete classes where already functioning as required. This worked without any other work or setup.

My Project is running .NET 4.5.1 MVC 5.1.2. Was very simple and did not effect the API functionality in any way.

Upvotes: 0

Christian Phillips
Christian Phillips

Reputation: 18759

I think you need something like this...

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

    // register all your components with the container here
    container.RegisterType<Interface, ClassThatImplementsInterface>();

    return container;
}

This tells your runtime which Concrete class to use when the Interface is present.

EDIT: Based on comments

Basically, you are telling the runtime which concrete type implements your interface(s). So, if you had an interface IRepository and you had two implementations, MockRepo & EFRepo. Your tests would likely pass MockRepo to any constructors that require it, but your DI would be responsible for registering the Interface against a runtime repository, in this case, EFRepo.

Obviously, during some testing of the application (i.e. you browsing the site), you might have the registration of the interface set up to use MockRepo, and then once you're ready to deploy, you can switch back to EFRepo in one location.

Upvotes: 0

Klaus Nji
Klaus Nji

Reputation: 18857

Since I am mixing Web API and MVC4 within the same project, I need to also ensure that Unity.WebApi.UnityDependencyResolver and Unity.Mvc4.UnityDependencyResolver are both setup as indicated here.

My Boostrapper.cs which now looks like this:

    public static IUnityContainer Initialise()
    {
      var container = BuildUnityContainer();
      GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
      DependencyResolver.SetResolver(new UnityDependencyResolver(container));

      return container;
    }

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

    public static void RegisterTypes(IUnityContainer container)
    {
        container.RegisterType<IAgencyResolver, AgencyByNameResolver>("ByName");
        container.RegisterType<IAgencyResolver, AgencyByCdeCodeResolver>("ByCode");
        container.RegisterType<IAgencyRepository, AgenciesRepository>();            
    }

allows both MVC and Web API controllers to be resolved successfully by Unity. To support both, I need NuGet packages Unity.Mvc4 and Unity.WebAPI. Hoping this does not bite me down the road.

Upvotes: 9

Related Questions