简体   繁体   English

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

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

I've created a C# ASP project with Unity MVC and Unity Web API configured. 我创建了一个配置了Unity MVC和Unity Web API的C#ASP项目。

I don't want to define the names of dependencies in objects which depend on them - I'm trying to keep that configuration alongside the other container configuration. 我不想在依赖它们的对象中定义依赖项的名称 -我正在尝试将该配置与其他容器配置一起保留。

But I'm struggling to determine how to do that with controllers? 但是我正在努力确定如何使用控制器来做到这一点? My controller looks like: 我的控制器看起来像:

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

And my current attempt at container configuration looks like: 我目前对容器配置的尝试如下所示:

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

But I end up with this exception: 但是我最终遇到了这个异常:

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

Which implies to me that it's not using the container to get the registered HomeController. 在我看来,这不是在使用容器来获取注册的HomeController。 I'm not sure how to wire this up correctly? 我不确定如何正确连接吗?

Solution

Taking the accepted answer, the exact solution which worked for me is registering this controller factory; 采取公认的答案,对我有用的确切解决方案是在该控制器工厂注册;

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

With this in Start() to actually register it, of course: 当然,使用Start()中的这个来实际注册它:

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

Controllers in MVC are created by controller factory. MVC中的控制器由控制器工厂创建。 If you want to user dependency injection, you have to hook to this controller factory and make your override that will make use of unity. 如果要进行用户依赖性注入,则必须挂接到该控制器工厂,并进行覆盖以使用统一性。

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

And in global.asax.cs: 在global.asax.cs中:

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

Alternative (lot less cool IMHO) is creation of base Controller - let's call it DIController that will call BuildUp() in constructor and inherit rest of the controllers from this DIController . 替代方案(不太酷的IMHO)是创建基本Controller -称之为DIController ,它将在构造函数中调用BuildUp()并从该DIController继承其余的控制器。 Needless to say you'll have to rewrite constructor based injection to method or property based injection. 不用说,您将不得不将基于构造函数的注入重写为基于方法或基于属性的注入。

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

相关问题 在Unity中,如何将命名依赖项与其他依赖项一起注入到构造函数中? - In Unity, how do I inject a named dependency into a constructor with other dependencies? 如何将依赖项注入模型? - How do I inject dependencies into a model? 如何将多个依赖项注入控制器? - How to inject multiple dependencies into controller? 如何使用Windsor将依赖项注入自定义RoleProvider? - How do I inject dependencies into a custom RoleProvider with Windsor? 如何将依赖项注入.Net Core项目中的自定义WebHostService中? - How do I inject dependencies into a custom WebHostService in a .Net Core project? 如何让Ninject将依赖项注入到我的MVC控制器中? - How do I let Ninject inject dependencies into my MVC controllers? 如何在单元测试的 Moq 中注入依赖项 - How do I inject dependencies in a Moq for a Unit Test 如何注入在Windsor注册的MEF [ImportingConstructor]依赖项? - How do I inject MEF [ImportingConstructor] dependencies registered with Windsor? 使用 Unity 如何将命名依赖项注入构造函数? - With Unity how do I inject a named dependency into a constructor? NET Core:如何将多个服务注入 controller? - NET Core: How do I inject multiple services into a controller?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM