Unity IoC和MVC 3 Beta - 将IRepository传递给Controller Constructor

时间:2010-10-15 14:06:49

标签: asp.net-mvc inversion-of-control asp.net-mvc-3

MVC 3有什么变化吗?我已尝试在Internet上设置Unity作为我的IoC容器的所有示例,但我一直收到错误,说Unity无法解析我的UserController。这是我的UserController上的构造函数:

public UserController(IUserService userService)
{
    _userService = userService;
}

我注册了IUserService,这不是问题。无论我尝试什么样的例子,我都会遇到错误。有没有人有一个很好的教程或代码,可以与Asp.Net MVC 3一起使用?

作为参考,我尝试过thisthisthisthis ......等等。

错误:

The type UserController cannot be constructed.  You must configure the container to supply this value.

ErrorLine:

controller = MvcUnityContainer.Container.Resolve(controllerType) as IController;

配置:

MvcUnityContainer.Container = new UnityContainer().RegisterType<IUserService, UserService>();

ControllerBuilder.Current.SetControllerFactory(typeof(UnityControllerFactory));

2 个答案:

答案 0 :(得分:3)

这适用于我的MVC3 RC。注意IControllerFactory现在在MVC3 RC中有GetControllerSessionBehavior。

UnityMvcControllerFactory.cs:

using System;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.Practices.Unity;
using System.Web.SessionState;

public class UnityMvcControllerFactory : IControllerFactory
{
  private IUnityContainer _container;
  private IControllerFactory _innerFactory;

  public UnityMvcControllerFactory(IUnityContainer container)
    : this(container, new DefaultControllerFactory())
  {
  }

  protected UnityMvcControllerFactory(IUnityContainer container,
                                   IControllerFactory innerFactory)
  {
    _container = container;
    _innerFactory = innerFactory;
  }

  public IController CreateController(RequestContext requestContext, string controllerName)
  {
    try
    {
      return _container.Resolve<IController>(controllerName.ToLowerInvariant());
    }
    catch (Exception)
    {
      return _innerFactory.CreateController(requestContext, controllerName);
    }
  }

  public void ReleaseController(IController controller)
  {
    _container.Teardown(controller);
  }

  public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
  {
    return SessionStateBehavior.Default;
  }
}

的Global.asax.cs:

  public class MvcApplication : System.Web.HttpApplication
  {
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
      filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterRoutes(RouteCollection routes)
    {
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

      routes.MapRoute(
          "Default", // Route name
          "{controller}/{action}/{id}", // URL with parameters
          new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
      );
    }

    protected void Application_Start()
    {
      // Register Types and Set Controller Factory 
      ConfigureUnityContainer();

      AreaRegistration.RegisterAllAreas();

      RegisterGlobalFilters(GlobalFilters.Filters);
      RegisterRoutes(RouteTable.Routes);
    }

    private static void ConfigureUnityContainer()
    {
      IUnityContainer container = new UnityContainer();

      // Set Controller Factory as UnityMvcControllerFactory
      ControllerBuilder.Current.SetControllerFactory(
          new UnityMvcControllerFactory(container)
      );
    }
  }

答案 1 :(得分:2)

回答你的问题“MVC3中发生了什么变化”:MVC3现在支持依赖注入。随着这种变化,重新设计了控制器对象的激活方式。查看Brad Wilson的帖子(以及关于MVC 3.0的整个系列)以获取更多信息:

http://bradwilson.typepad.com/blog/2010/10/service-location-pt10-controller-activator.html

以前通过派生DefaultControllerFactory实现IControllerFactory而只是为了依赖注入而覆盖GetControllerInstance方法的开发人员现在应该实现IControllerActivator。

简而言之,统一控制器工厂(以及Ninject控制器工厂)可能会破坏,直到他们发布新的兼容版本。一个快速谷歌找到了this,但我不知道它是否有效。