【问题标题】:Where is the "magic" happening when a Controller instantiates the correct implementation of the Interface in Web API DI?当控制器在 Web API DI 中实例化接口的正确实现时,“魔法”在哪里发生?
【发布时间】:2013-12-30 20:07:29
【问题描述】:

在我看来,当涉及到 Web API 控制器中的 DI 时,兔子在某处被拉了出来。

我觉得: 0)Web API项目中的Controller可以调用各种类进行实例化,这些类都实现了Controller所依赖的接口。例如,使用此控制器代码:

private readonly IDepartmentRepository _deptsRepository;

public DepartmentsController(IDepartmentRepository deptsRepository)
{
    if (deptsRepository == null)
    {
        throw new ArgumentNullException("deptsRepository is null");
    }
    _deptsRepository = deptsRepository;
}

...“deptsRepository”可以是实现 IDepartmentRepository 并检索测试数据的类,也可以是实现 IDepartmentRepository 并检索生产数据的类,或者(等等)

1) Web API 根据客户端调用的 URI 来决定调用哪个控制器,而 Web API 根据它是什么类型(GET、POST)等来决定调用该控制器中的哪个方法以及它是什么参数,如果任何,都与它一起传递。

2) Castle Windsor 使用自己的替代路由引擎拦截控制器的这种自动控制。

我不明白的是开发人员在哪里注入了实现控制器期望的接口的具体类。 IOW,如果我想运行从测试数据中提取的类,我在哪里添加代码来指定它?我认为它会在 Global.asax.cs 中的某个地方,类似于(伪代码):

// Use test data for now
DeptsControllerClass = TestDataClass;
//DeptsControllerClass = ProductionDataClass;

IOW,在哪里指定,“这一次,我希望你注入这个实现所需接口的具体类”?

【问题讨论】:

    标签: dependency-injection asp.net-web-api castle-windsor global-asax asp.net-web-api-routing


    【解决方案1】:

    正如您在第 1 点所写的,路由和 IoC 是两个不同的东西。

    一旦路由引擎确定必须调用哪个控制器,就会调用“控制器工厂”。

    WebApi 框架允许插入你自己的工厂如下:

    GlobalConfiguration.Configuration.Services.Replace(
        typeof(IHttpControllerActivator),
        new WindsorCompositionRoot(this.container));
    

    Mark Seemann post 上阅读有关 webapi&windsor 管道的更多信息。

    将使用哪种具体来满足给定的接口依赖关系,这取决于您选择在上面的工厂中使用的 ioc。使用 Windsor,您可以/应该在 Installers 中链接接口和混凝土。

    让我试着回顾一下整个过程 1)设置路由以链接url与控制器 2) 创建容器并使用安装程序注册所有组件 3)用你最喜欢的ioc容器替换默认控制器工厂(温莎,我想:-)) 4) 享受魔法。

    所有这些步骤都发生在 Global.asax 中的 Application_start 中

    【讨论】:

    • 好的;我想我可能有我需要的所有代码,我只是不知道如何“连接”;具体来说,我需要做什么才能将我的存储库/控制器“链接”到我的 DepartmentProviderInstaller 类:stackoverflow.com/questions/20843810/…
    • IOW,我如何“在安装程序中链接界面和混凝土”?
    • IWindsorInstaller 需要 void Install(IWindsorContainer container, IConfigurationStore store) 所以在 Install 方法中你有容器,所以你只需要注册一个组件。最简单的注册是 container.Register(Component.For().ImplementedBy());
    猜你喜欢
    • 2011-07-01
    • 2023-03-05
    • 2016-10-29
    • 1970-01-01
    • 2014-03-12
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多