Home Dashboard Directory Help
Search

IoC Not Working In MVC4 by timtas


Status: 

Closed
 as By Design Help for as By Design


2
2
Sign in
to vote
Type: Bug
ID: 725313
Opened: 2/16/2012 1:23:55 PM
Access Restriction: Public
Moderator Decision: Sent to Engineering Team for consideration
0
Workaround(s)
view
1
User(s) can reproduce this bug

Description

MVC4 gives me an error that my controller does not have a default constructor. Of course it does not, but StructureMap can handle that. It's an ApiController.

In app startup:

    var container = Bootstrapper.RegisterDependencies();
    DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));

In the Bootstrapper, I register controllers with SM:

    factory.Scan(x =>
    {
        x.AddAllTypesOf<IHttpController>();
        x.AddAllTypesOf<IController>();
    });

I have confirmed that the ApiController in question is in fact registered with SM.

I even created a controller factory and told SM about that too (even though I think I should not have to do that):

    factory.For<IHttpControllerFactory>().Use<HttpControllerFactory>();

When requesting an action on the controller, my StructureMapDependencyResolver is never called. Neither is my HttpControllerFactory.

This is the stack trace:

at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpControllerContext controllerContext, Type controllerType)\u000d\u000a
at System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateInstance(HttpControllerContext controllerContext, HttpControllerDescriptor controllerDescriptor)\u000d\u000a
at System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateController(HttpControllerContext controllerContext, String controllerName)\u000d\u000a
at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal(HttpRequestMessage request, CancellationToken cancellationToken)\u000d\u000a
at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)

As you can see the dispatcher uses the default controller factory, which uses the default activator, which obviously does not use my dependency resolver that I have told the framework to use.

I can't find any other way to configure the controller factory for IHttpControllers, so I'm blocked.
Details
Sign in to post a comment.
Posted by Microsoft on 3/21/2012 at 2:48 PM
Hi everyone,

As several folks have discovered, MVC and Web API use two different service resolvers to create their services. We expect that the various service resolver implementations out there (such as Ninject, StructureMap, and many others) will implement the Web API service resolver in addition to the MVC service resolver, so people won't have a problem when they install those packages. Fortunately, the two interfaces have identical APIs, so implementing both is very easy.

The MVC and Web API service resolvers can't be the same because there is no dependency between the two DLLs in which they are defined. We are not planning to add that dependency because would make other scenarios more complicated, such as people who only want to use one framework and not the other.

Thanks,
The ASP.NET Team
Posted by Microsoft on 3/11/2012 at 11:35 PM
Thank you for attaching the project to help us investigate this issue. Your issue has been routed to the appropriate VS development team for investigation. We will contact you if we require any additional information.
Posted by Nick Berardi on 2/20/2012 at 5:29 AM
Hi timtas,

Figured out this problem. MVC and Http don't use the same dependency injector. Sort of a huge pain in the ass, because who uses more than one Dependency Injector in their code. But here is the current class to setup everything for Http.

GlobalConfiguration.Configuration.ServiceResolver.SetResolver(...)

Also same is true for everything else. ModelBinders seem to be some where else too.
Posted by timtas on 2/18/2012 at 6:07 AM
I attached a solution that demonstrates the problem. Run the app and make a GET request at:

    http://localhost:55827/api/test/1 (port may vary)

Expected behavior is that my TestController should be instantiated by StructureMapDependencyResolver. Instead the framework is trying to instantiate the controller via parameterless c-tor.

Here is the response I get.

<Exception xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ExceptionType>System.InvalidOperationException</ExceptionType>
<Message>
An error occurred when trying to create a controller of type 'Mvc4IocProblem.Controllers.TestController'. Make sure that the controller has a parameterless public constructor.
</Message>
<StackTrace>
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpControllerContext controllerContext, Type controllerType)
at System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateInstance(HttpControllerContext controllerContext, HttpControllerDescriptor controllerDescriptor)
at System.Web.Http.Dispatcher.DefaultHttpControllerFactory.CreateController(HttpControllerContext controllerContext, String controllerName)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
</StackTrace>
<InnerException>
<ExceptionType>System.ArgumentException</ExceptionType>
<Message>
Type 'Mvc4IocProblem.Controllers.TestController' does not have a default constructor
</Message>
<StackTrace>
at System.Linq.Expressions.Expression.New(Type type)
at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpControllerContext controllerContext, Type controllerType)
</StackTrace>
</InnerException>
</Exception>
Posted by MS-Moderator08 [Feedback Moderator] on 2/17/2012 at 2:39 AM
Thank you for reporting this issue. Could you please attach a sample project to help us reproduce this issue?
Posted by MS-Moderator01 on 2/16/2012 at 1:45 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.
File Name Submitted By Submitted On File Size  
Mvc4IocProblem.zip 2/18/2012 3.2 MB