Search code examples
c#asp.net-mvcdependency-injection

Make sure that the controller has a parameterless public constructor. ASP.NET MVC


I have an existing ASP.NET MVC controller with a parameterized constructor and it works just fine until I tried to inject a new interface in the constructor.

Here is an example of the original code that works:

public class HomeController : BaseController
{
    private readonly IApartment apartment;
  
    public HomeController(IApartment apartment)
    {
        this.apartment = apartment ?? throw new ArgumentNullException(nameof(apartment));
    }
}

And in UnityConfig.cs:

public static void RegisterComponents()
{
    Container.RegisterType<IApartment, Apartment>();
}

I have a new interface that I would like to use in this controller.

Here is how I modified the code:

public class HomeController : BaseController
{
    private readonly IApartment apartment;
    private readonly ITenant tenant;
    
    public HomeController(IApartment apartment, ITenant tenant)
    {
        this.apartment = apartment ?? throw new ArgumentNullException(nameof(apartment));
        this.tenant = tenant ?? throw new ArgumentNullException(nameof(tenant));
    }
}

I have also registered it in UnityConfig.cs:

public static void RegisterComponents()
{
    Container.RegisterType<IApartment, Apartment>();
    Container.RegisterType<ITenant, Tenant>();
}

When I run my project I get this error:

An error occurred when trying to create a controller of type 'PropertyManager.UI.Controllers.HomeController'. Make sure that the controller has a parameterless public constructor.

When I remove ITenant references, then the project runs.

Can someone please assist? Where do I get this wrong?


Solution

  • One problem that you may want to look for is if Tenant has dependencies of its own, e.g.

    public class Tenant
    {
        public Tenant(IFoo foo)
        {
        }
    
        // Implementation goes here...
    }
    

    In that case, you'd also need to register an implementation for IFoo, and so on recursively, if the dependency graph is deeper than that:

    Container.RegisterType<IFoo, Foo>();
    

    I admit that that's not what the error message seems to indicate, but IIRC, there were versions of ASP.NET MVC that were vague like that.

    In any case, this is one of several reasons that today I generally recommend Pure DI instead of DI Containers. With Pure DI, such a problem would have been an easily locatable compiler error, rather than an obscure run-time exception.