4

我正在尝试使用 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

我不确定我需要在哪里更改?

4

2 回答 2

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 包中的内容非常相似(参见此文件中的第 123 行)。

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


更新

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

如果依赖解析器中不存在 IControllerActivator,我们将要求依赖解析器通过调用 GetService(controllerType) 创建具体的控制器类型。(引自Brad Wilson 的博客

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

于 2013-08-11T18:30:32.400 回答
0

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

于 2015-05-25T13:51:54.690 回答