Simple Injector - No parameterless constructor defined for this object when resolving MVC controller
Asked Answered
T

2

10

I have a new MVC web project which I'm using MVC and Web API in. I have setup Simple Injector (version 2.5.2 from NuGet) using the following code in my global file

// Register Injectors
SimpleInjectorConfig.Register();

In my SimpleInjectorConfig.cs file i have

public class SimpleInjectorConfig
{
    public static void Register() {
        // Create the container as usual.
        Container container = new Container();

        // services
        container.Register<IService, MyService>();

        // data
        container.Register<IRepository, MyRepository>();

        // Register your types, for instance using the RegisterWebApiRequest
        // extension from the integration package:
        container.RegisterMvcControllers(
            System.Reflection.Assembly.GetExecutingAssembly());

        container.RegisterMvcAttributeFilterProvider();

        // This is an extension method from the integration package.
        container.RegisterWebApiControllers(GlobalConfiguration.Configuration);

        // verify its all ok
        container.Verify();

        // add dependency
        GlobalConfiguration.Configuration.DependencyResolver = 
            new SimpleInjectorWebApiDependencyResolver(container);
    }
}

Now I have 2 controllers, 1 is a Web API controller and 1 is a normal MVC controller.

My Web API controller works fine and looks like this

public class MyApiController : ApiController
{
    private IService _service;

    public MyApiController(IService service)
    {
        _service = service;
    }

    public IHttpActionResult Get(int id)
    {
        // I get my entity here and return it
        EntityObject myEntity = _service.Get(id);
        return Ok(myEntity);
    }
}

As I said the above code works fine, I can execute the URL and it returns what I would expect.

Now I have my MVC controller, that looks very similar to the above, here it is

public class MyController : Controller
{
    private IService _service;

    public MyController(IService service)
    {
        _service = service;
    }

    public ActionResult Index()
    {
        return Search();
    }

    public ActionResult Search()
    {
        return View();
    }
}

Now I can't understand at all why I keep getting the following error. I cannot add a public constructor as that causes an error with Simple Injector.

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

   System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
   System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +113
   System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +232
   System.Activator.CreateInstance(Type type, Boolean nonPublic) +83
   System.Activator.CreateInstance(Type type) +66
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +110

[InvalidOperationException: An error occurred when trying to create a controller of type 'my.project.Web.Controllers.MyController'. Make sure that the controller has a parameterless public constructor.]
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +247
   System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +438
   System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +257
   System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +328
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +157
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +88
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +50
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

If someone could point me in the right direction, that would be great.

Turino answered 22/9, 2014 at 11:39 Comment(0)
B
26

The reason for getting this error is because you are missing the following registration (as explained in the MVC integration guide):

DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));

MVC and Web API both have their own abstraction for resolving dependencies (both called 'dependency resolver'). Since you didn't set the resolver for MVC, MVC uses the default resolution mechanism for creating MVC controllers, but this requires controllers to have a default constructor.

Calling DependencyResolver.SetResolver will solve the problem.

Benildis answered 22/9, 2014 at 12:1 Comment(3)
OMG I've spent about 5 hours on this. thanks savior.Zobe
How can we solve the same issue in latest version of simple injector ?version 4.3.0.0 that i am using. Can you please help ?Excretory
The documentation is up to date and works for v4.3. If you are keeping having trouble, you can post a new question.Benildis
G
3

For Web API Projects, the SetResolver method described above will compile but when the application is run, you'll get an ArgumentException error: "Additional information: The type SimpleInjector.Integration.WebApi.SimpleInjectorWebApiDependencyResolver does not appear to implement Microsoft.Practices.ServiceLocation.IServiceLocator."

You'll resolved this issue by setting the DependencyResolver to a SimpleInjectorWebApiDependencyResolver and pass in your container, like below.

GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
Gd answered 23/8, 2017 at 17:54 Comment(1)
Solved the issue for me. In my case I had a web api and my api endpoints in the ValuesController. and I was using SimpleInjector. I was getting a runtime error when I tried to access a Get endpoint which returned this error instead of the expected XML response. Adding the above line solved the problem for me.Lilley

© 2022 - 2024 — McMap. All rights reserved.