开发者

Unity IoC and MVC 3 Beta - Passing IRepository to Controller Constructor

Did something change in MVC 3? I have tried all the examples on the Internet for setting up Unity as my IoC Container, but I keep getting an error saying that Unity cannot resolve my UserController. Here is my constructor on my UserController:

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

I have the IUserService registered, that is not the problem. I keep getting errors, no matter what example I try. Does anyone have a good tutorial, or code, that works with Asp.Net MVC 开发者_如何学运维3?

For reference, I have tried this, this, this, and this ... and tons of others.

Error:

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

ErrorLine:

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

Configuration:

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

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


This worked for me for MVC3 RC. Notice IControllerFactory now has GetControllerSessionBehavior in MVC3 RC.

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


To answer your question "What has changed in MVC3": MVC3 now has native support for dependency injection. Along with that change has come a redesign of the way controller objects are activated. Check out Brad Wilson's post (and the whole series about MVC 3.0) for more information:

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

Developers who previously implemented IControllerFactory by deriving from DefaultControllerFactory just to override the GetControllerInstance method for dependency injection purposes should now implement IControllerActivator instead.

In short, the unity controller factory (as well as the Ninject controller factory) are probably going to be broken until they release a new compatible version. A quick google did find this, however I have no idea if it works.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜