簡體   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