Make sure that the controller has a parameterless public constructor error

C#asp.net Mvcasp.net Web-ApiUnity Container

C# Problem Overview


I have followed this tutorial which has worked great, until I modified my DbContext to have an additional constructor. I am now having issues with the resolution and not sure what to do to fix this. Is there an easy way to force it to grab the parameterless constructor or I am approaching this incorrectly?

DbContext with two constructors:

public class DashboardDbContext : DbContext
{
    public DashboardDbContext() : base("DefaultConnection") { }

    public DashboardDbContext(DbConnection dbConnection, bool owns)
        : base(dbConnection, owns) { }
}

SiteController constructor:

private readonly IDashboardRepository _repo;

public SiteController(IDashboardRepository repo)
{
    _repo = repo;
}

Repository:

DashboardDbContext _context;

public DashboardRepository(DashboardDbContext context)
{
    _context = context;
}

UnityResolver code:

public class UnityResolver : IDependencyResolver
{
    private readonly IUnityContainer _container;

    public UnityResolver(IUnityContainer container)
    {
        _container = container;
    }

    public object GetService(Type serviceType)
    {
        try
        {
            return _container.Resolve(serviceType);
        }
        catch (ResolutionFailedException)
        {
            return null;
        }
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        try
        {
            return _container.ResolveAll(serviceType);
        }
        catch (ResolutionFailedException)
        {
            return new List<object>();
        }
    }

    public IDependencyScope BeginScope()
    {
        var child = _container.CreateChildContainer();
        return new UnityResolver(child);
    }

    public void Dispose()
    {
        _container.Dispose();
    }
}

WebApiConfig:

var container = new UnityContainer();
container.RegisterType<IDashboardRepository, DashboardRepository>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);

Error from WebApi Call:

> System.InvalidOperationException: An error occurred when trying to create a controller of type 'SiteController'. Make sure that the controller has a parameterless public constructor.

at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) 
at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request) 
at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken) 
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()

> InnerException: System.ArgumentException: Type 'Dashboard.Web.Controllers.SiteController' does not have a default constructor.

at System.Linq.Expressions.Expression.New(Type type) 
at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType) 
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator) 
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)

The tutorial was great and has been working well for me up until I added the second constructor.

C# Solutions


Solution 1 - C#

What's happening is that you're bitten by this problem. Basically, what happened is that you didn't register your controllers explicitly in your container. Unity tries to resolve unregistered concrete types for you, but because it can't resolve it (caused by an error in your configuration), it return null. It is forced to return null, because Web API forces it to do so due to the IDependencyResolver contract. Since Unity returns null, Web API will try to create the controller itself, but since it doesn't have a default constructor it will throw the "Make sure that the controller has a parameterless public constructor" exception. This exception message is misleading and doesn't explain the real cause.

You would have seen a much clearer exception message if you registered your controllers explicitly, and that's why you should always register all root types explicitly.

But of course, the configuration error comes from you adding the second constructor to your DbContext. Unity always tries to pick the constructor with the most arguments, but it has no idea how to resolve this particular constructor.

So the real cause is that you are trying to use Unity's auto-wiring capabilities to create the DbContext. DbContext is a special type that shouldn't be auto-wired. It is a framework type and you should therefore fallback to registering it using a factory delegate:

container.Register<DashboardDbContext>(
    new InjectionFactory(c => new DashboardDbContext())); 

Solution 2 - C#

In my case, it was because of exception inside the constructor of my injected dependency (in your example - inside DashboardRepository constructor). The exception was caught somewhere inside MVC infrastructure. I found this after I added logs in relevant places.

Solution 3 - C#

I had the same issue and I resolved it by making changes in the UnityConfig.cs file In order to resolve the dependency issue in the UnityConfig.cs file you have to add:

public static void RegisterComponents()    
{
    var container = new UnityContainer();
    container.RegisterType<ITestService, TestService>();
    DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}

Solution 4 - C#

I had the same problem. I googled it for two days. At last I accidentally noticed that the problem was access modifier of the constructor of the Controller. I didn’t put the public key word behind the Controller’s constructor.

public class MyController : ApiController
    {
        private readonly IMyClass _myClass;

        public MyController(IMyClass myClass)
        {
            _myClass = myClass;
        }
    }

I add this experience as another answer maybe someone else made a similar mistake.

Solution 5 - C#

Sometimes because you are resolving your interface in ContainerBootstraper.cs it's very difficult to catch the error. In my case there was an error in resolving the implementation of the interface I've injected to the api controller. I couldn't find the error because I have resolve the interface in my bootstraperContainer like this: container.RegisterType<IInterfaceApi, MyInterfaceImplementaionHelper>(new ContainerControlledLifetimeManager());
then I've adde the following line in my bootstrap container : container.RegisterType<MyController>(); so when I compile the project , compiler complained and stopped in above line and showed the error.

Solution 6 - C#

If you are using UnityConfig.cs to resister your type's mappings like below.

public static void RegisterTypes(IUnityContainer container)
    {
     container.RegisterType<IProductRepository, ProductRepository>();
    }
    

You have to let the know **webApiConfig.cs** about Container

config.DependencyResolver = new Unity.AspNet.WebApi.UnityDependencyResolver(UnityConfig.Container);

Solution 7 - C#

If you have an interface in your controller

public myController(IXInterface Xinstance){}

You must register them to Dependency Injection container.

container.Bind<IXInterface>().To<XClass>().InRequestScope();

Solution 8 - C#

I've got this error when I accidentally defined a property as a specific object type, instead of the interface type I have defined in UnityContainer.

For example:

Defining UnityContainer:

var container = new UnityContainer();
container.RegisterInstance(typeof(IDashboardRepository), DashboardRepository);
config.DependencyResolver = new UnityResolver(container);

SiteController (the wrong way - notice repo type):

private readonly DashboardRepository _repo;

public SiteController(DashboardRepository repo)
{
    _repo = repo;
}

SiteController (the right way):

private readonly IDashboardRepository _repo;

public SiteController(IDashboardRepository repo)
{
    _repo = repo;
}

Solution 9 - C#

In my case, Unity turned out to be a red herring. My problem was a result of different projects targeting different versions of .NET. Unity was set up right and everything was registered with the container correctly. Everything compiled fine. But the type was in a class library, and the class library was set to target .NET Framework 4.0. The WebApi project using Unity was set to target .NET Framework 4.5. Changing the class library to also target 4.5 fixed the problem for me.

I discovered this by commenting out the DI constructor and adding default constructor. I commented out the controller methods and had them throw NotImplementedException. I confirmed that I could reach the controller, and seeing my NotImplementedException told me it was instantiating the controller fine. Next, in the default constructor, I manually instantiated the dependency chain instead of relying on Unity. It still compiled, but when I ran it the error message came back. This confirmed for me that I still got the error even when Unity was out of the picture. Finally, I started at the bottom of the chain and worked my way up, commenting out one line at a time and retesting until I no longer got the error message. This pointed me in the direction of the offending class, and from there I figured out that it was isolated to a single assembly.

Solution 10 - C#

I really, really hope this answer helps someone else from wasting a day and a half of messing around with; Ninject, MVC design pattern, Global.asax, Web Common files etc etc.

The error itself was completely misleading in my case.

My entire application was working sound with the exception of when I called one particualr controller lets call TestController.

Test controller was using Ninject to inject an interface lets call ITest like so -

public class TestController : ApiController
{
    private readonly ITest _test;

    public TestController (ITest test)
    {
        _test= test;
    }

I was making a simple GET request to one of the methods in TestController and was getting the aforementioned error for this threads question.

I eventually boiled it down to the error only occuring when ITest was injected as a parameter (as I tested a different interface and it worked soundly!)

This led me to check the Test class and realsied that I had injected an instance of itself into it! Like so -

public class Test: ITest
{
    private readonly ITest_test;

    public Test(ITest test)
    {
        _test = test;
    }

Thus resulting in the entire call falling over as an unhandled exception and returning a completely bizarre error that didn't help me at all!

Solution 11 - C#

Install Nuget Package Unit.WebAP instead of Unity.MVC5 Make sure the correct unity package is installed using nuget

I Installed Unity.MVC5 and was facing similar exception "parameterless constructor"

 public static void RegisterComponents()
{
    var container = new UnityContainer();

    // register all your components with the container here
    // it is NOT necessary to register your controllers

    // e.g. container.RegisterType<ITestService, TestService>();
    container.RegisterType<ICar, Tesla>();
    GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionscarpacciView Question on Stackoverflow
Solution 1 - C#StevenView Answer on Stackoverflow
Solution 2 - C#IllidanView Answer on Stackoverflow
Solution 3 - C#befree2jView Answer on Stackoverflow
Solution 4 - C#BobsView Answer on Stackoverflow
Solution 5 - C#Amir978View Answer on Stackoverflow
Solution 6 - C#Vinay PatelView Answer on Stackoverflow
Solution 7 - C#Ahmet ArslanView Answer on Stackoverflow
Solution 8 - C#MasterPieceView Answer on Stackoverflow
Solution 9 - C#Katie KilianView Answer on Stackoverflow
Solution 10 - C#EbikeneserView Answer on Stackoverflow
Solution 11 - C#rajquestView Answer on Stackoverflow