Reputation: 12663
I am trying to setup IoC using StructureMap for my ASP.NET MVC 4 site. Here is my StructureMapDependencyResolver
class:
public class StructrueMapDependencyResolver : IDependencyResolver
{
public object GetService(Type serviceType)
{
return IocContainer.GetInstance(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return IocContainer.GetAllInstances(serviceType);
}
}
Here is part of my IocContainer
public static class IocContainer
{
....
public static object GetInstance(Type t)
{
return ObjectFactory.TryGetInstance(t);
}
public static IEnumerable<object> GetAllInstances(Type t)
{
return ObjectFactory.GetAllInstances(t).Cast<object>();
}
}
Here is what my Global.aspx.cs looks like
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
IocContainer.RegisterAllTypes(Server.MapPath("~\\Bin"), AssemblyList.MyAssemblies);
DependencyResolver.SetResolver(new StructrueMapDependencyResolver());
}
}
Finally I have a simple controller that depends on a service:
public class ManagePostController: Controller
{
private ISomeService _someService;
public ManagePostController(ISomeService svc)
{
_someService= svc;
}
}
When I start my website, got the following exception:
No parameterless constructor defined for this object.
[InvalidOperationException: An error occurred when trying to create a controller of type 'Foothill.WebAdmin.Controllers.ManagePostController'. Make sure that the controller has a parameterless public constructor.] System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +247
I am not sure where I need to change?
Upvotes: 4
Views: 7275
Reputation: 5405
I had the same problem using IoC container and googled for hours about it but could not get rid of it.finally I install last update of Visual Studio(VS Version 2013 and update3 in my case) and the probelm get solved.
Upvotes: 0
Reputation: 40556
Replace your IocContainer.GetInstance(Type)
implementation with the following:
public static object GetInstance(Type t)
{
return t.IsAbstract || t.IsInterface
? ObjectFactory.TryGetInstance(t)
: ObjectFactory.GetInstance(t);
}
The ASP.NET MVC extensibility model will attempt to resolve various components (e.g. IControllerActivator
) which are optional (if you return null
, MVC will use the default components instead). That's why we have the ObjectFactory.TryGetInstance
call - this will only resolve a component if you explicitly configure it within the container.
For resolving controllers (which are concrete types) ObjectFactory.GetInstance
should be used - this creates an instance even though the controller type was never explicitly configured.
The code snippet above is what I use in my projects and I just realized it's very similar to what is present in the StructureMap MVC4 Nuget package (see line 123 in this file).
By the way, I think you could simply use the NuGet package instead of going through these steps yourself.
Regarding IControllerActivator
: that's just another extensibility point. If no controller activator is registered, the dependency resolver is used instead:
If there is no IControllerActivator present in the dependency resolver, we will then ask the dependency resolver to create the concrete controller type by calling GetService(controllerType). (quote from Brad Wilson's blog)
Also, an explanation of why there are both IDependencyResolver
and IControllerActivator
: http://forums.asp.net/post/4241343.aspx
Upvotes: 4