尝试将IoC用于asp.net mvc 4,"没有为此对象定义无参数构造函数"例外

时间:2013-08-11 17:30:30

标签: asp.net-mvc-4 structuremap

我正在尝试使用StructureMap为我的ASP.NET MVC 4站点设置IoC。这是我的StructureMapDependencyResolver课程:

    public class StructrueMapDependencyResolver : IDependencyResolver
    {        
        public object GetService(Type serviceType)
        {
            return IocContainer.GetInstance(serviceType);
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            return IocContainer.GetAllInstances(serviceType);
        }
    }

这是我的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>();
    }
}

这是我的Global.aspx.cs的样子

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());
        }
    } 

最后,我有一个依赖于服务的简单控制器:

  public class ManagePostController: Controller
  {
      private ISomeService _someService;

      public ManagePostController(ISomeService svc)
      {
          _someService= svc;
      }
  }

当我启动我的网站时,遇到以下异常:

  

没有为此对象定义无参数构造函数。

     

[InvalidOperationException:尝试创建“Foothill.WebAdmin.Controllers.ManagePostController”类型的控制器时发生错误。确保控制器具有无参数的公共构造函数。]      System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext,Type controllerType)+247

我不确定我需要改变的地方?

2 个答案:

答案 0 :(得分:4)

将您的IocContainer.GetInstance(Type)实施替换为以下内容:

public static object GetInstance(Type t)
{
    return t.IsAbstract || t.IsInterface
                    ? ObjectFactory.TryGetInstance(t)
                    : ObjectFactory.GetInstance(t);
}

ASP.NET MVC可扩展性模型将尝试解析可选的各种组件(例如IControllerActivator)(如果返回null,则MVC将使用默认组件)。这就是我们进行ObjectFactory.TryGetInstance调用的原因 - 如果您在容器中明确配置它,它将只解析一个组件。

对于解析控制器(具体类型)应该使用ObjectFactory.GetInstance - 即使从未显式配置控制器类型,也会创建一个实例。

上面的代码片段是我在项目中使用的代码片段,我刚刚意识到它与StructureMap MVC4 Nuget包中的内容非常相似(参见this file中的第123行)。

顺便说一下,我认为你可以简单地使用the NuGet package而不是自己完成这些步骤。


更新

关于IControllerActivator:这只是另一个可扩展性点。如果未注册控制器激活器,则使用依赖性解析器:

  

如果依赖项解析程序中没有IControllerActivator,我们将通过调用GetService(controllerType)请求依赖项解析程序创建具体的控制器类型。(引自Brad Wilson's blog

此外,解释为什么同时存在IDependencyResolverIControllerActivatorhttp://forums.asp.net/post/4241343.aspx

答案 1 :(得分:0)

我在使用IoC容器时遇到了同样的问题并且谷歌搜索了几个小时但是无法摆脱它。最后我安装了Visual Studio的最新更新(VS版本2013和我的情况下的update3)并且问题得到了解决。< / p>