Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 974
Gillardo Avatar asked Sep 22 '14 11:09

Gillardo


2 Answers

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.

like image 187
Steven Avatar answered Oct 14 '22 09:10

Steven


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);
like image 22
sondlerd Avatar answered Oct 14 '22 10:10

sondlerd