2

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.

错误线:

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

配置:

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

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

2 回答 2

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

全球.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)
      );
    }
  }
于 2010-11-23T16:44:26.760 回答
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 。

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

于 2010-10-15T17:38:41.023 回答