繁体   English   中英

如何将命名依赖项注入到控制器中?

[英]How do I inject named dependencies in to a controller?

我创建了一个配置了Unity MVC和Unity Web API的C#ASP项目。

我不想在依赖它们的对象中定义依赖项的名称 -我正在尝试将该配置与其他容器配置一起保留。

但是我正在努力确定如何使用控制器来做到这一点? 我的控制器看起来像:

namespace MyService.Controllers
{
    public class HomeController : Controller
    {
        private ITest test;

        public HomeController(ITest test)
        {
            this.test = test;
        }

        public ActionResult Index()
        {
            ViewBag.Title = "Home Page";

            return View();
        }
    }
}

我目前对容器配置的尝试如下所示:

container.RegisterType<ITest>("bar",
    new InjectionFactory(c => new TestImpl1()));

container.RegisterType<ITest>("foo",
    new InjectionFactory(c => new TestImpl2()));

container.RegisterType<HomeController>("Home",
    new InjectionFactory(c => new HomeController(
        c.Resolve<ITest>("foo")
    )));

但是我最终遇到了这个异常:

The current type, MyService.App_Start.ITest, is an interface and cannot be constructed. Are you missing a type mapping?

在我看来,这不是在使用容器来获取注册的HomeController。 我不确定如何正确连接吗?

采取公认的答案,对我有用的确切解决方案是在该控制器工厂注册;

public class UnityControllerFactory : DefaultControllerFactory
{
    private readonly IUnityContainer _container;

    public UnityControllerFactory(IUnityContainer container)
    {
        _container = container;
    }

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
        {
            return base.GetControllerInstance(requestContext, null);
        }

        return _container.Resolve(controllerType) as IController;
    }
}

当然,使用Start()中的这个来实际注册它:

ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory(container));

MVC中的控制器由控制器工厂创建。 如果要进行用户依赖性注入,则必须挂接到该控制器工厂,并进行覆盖以使用统一性。

public class MgsMvcControllerFactory : DefaultControllerFactory {
  protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) {
    // our controller instance will have dependency injection working
    if (!ServiceLocator.IoC.IsServiceRegistered(controllerType, controllerType.FullName)) {
      ServiceLocator.IoC.RegisterType(controllerType, controllerType.FullName, new ContainerControlledLifetimeManager())
    }
    return ServiceLocator.IoC.Resolve<IController>(controllerType.FullName);
  }
}

在global.asax.cs中:

protected void Application_Start() {
  // initialization of unity container
  ServiceLocator.IoC = ...; 
  var factory = new MgsMvcControllerFactory()
  ControllerBuilder.Current.SetControllerFactory(factory);
}

替代方案(不太酷的IMHO)是创建基本Controller -称之为DIController ,它将在构造函数中调用BuildUp()并从该DIController继承其余的控制器。 不用说,您将不得不将基于构造函数的注入重写为基于方法或基于属性的注入。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM