如何指定我希望控制器的构造函数接收的类实例(使用Web API,DI和Castle Windsor时)?

克莱·香农(B. Clay Shannon)

也许我在这里这里的问题还不够清楚,所以我将尝试减少冗长性,同时又不降低清晰度。

假设我的控制器使用DI(您可以“用脑袋说出它-不必大声说出来”);所以它看起来像这样:

private readonly IDepartmentRepository _deptsRepository;

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

这样,我可以拦截Web API路由机制,让它将实现IDepartmentRepository的特定类传递给Controller的构造函数。因此,如果我的界面是:

public interface IDepartmentRepository
{
    int Get();
    IEnumerable<Department> Get(int ID, int CountToFetch);
    Department Add(Department item);
    void Post(Department dept);
    void PostDepartment(int accountid, string name);
    void Put(Department dept);
    void Delete(int Id);
}

...我可以有这样的课程:

public class DepartmentRepositoryProductionData : IDepartmentRepository
{
    private readonly List<Department> departments = new List<Department>();

    public DepartmentRepository()
    {
        using (var conn = new OleDbConnection(
            @"Provider=Microsoft.ACE.OLEDB.12.0;User ID=BlaBlaBla..."))
        {
...                        

...还有这个:

public class DepartmentRepositoryTestData : IDepartmentRepository
{
    private readonly List<Department> departments = new List<Department>();

    public DepartmentRepository()
    {
        // Load test data from an XML file (or text file, or whatever)
...                        

现在,这只是花花公子,但我如何/在何处指定我希望DepartmentRepositoryTestData(或DepartmentRepositoryProductionData)的实例成为Controller实例化的实例?我衷心地接受将类的标识延迟到运行时的概念,但是即使在阅读了很多有关DI的知识之后,我也缺少了有关如何以及在何处指定控制器将接收哪个类(实现所需接口)的部分。在其构造函数arg中。

它是由客户端,IOW通过URI中传递的内容指定的吗?我认为不会,但是我有点困惑,因此“一切皆有可能”。

更新

由于这显然还不够清楚,因此我将添加以下内容:

为了使这种抽象(Controller构造函数的接口arg)具有任何值,必须有多个实现该接口的类,对吗?这可以是“测试数据”类和“生产数据”类,也可以是“加利福尼亚披萨”类和“纽约披萨”类,或者是全部实现的加利福尼亚,纽约,芝加哥和意大利类IPizzaPie。

但是某个地方的交通警察必须说:“实例化加州阶级”或“实例化纽约阶级”等。

这是我的问题:交通警察(类实例决策者)在哪里/在哪里,我们如何告诉它要通过哪个类?

更新2

似乎指定类类型的地方可能是在调用此构造函数(在我的“ WindsorCompositionRoot.cs”中)时:

public IHttpController Create(
    HttpRequestMessage request,
    HttpControllerDescriptor controllerDescriptor,
    Type controllerType)
{
    var controller =
        (IHttpController)this.container.Resolve(controllerType);

    request.RegisterForDispose(
        new Release(
            () => this.container.Release(controller)));

    return controller;
}

...但是我仍然不知道谁叫这个(IHttpController)...

更新3

可以帮助,所以做

菲尔·桑德勒

通常,如果您正在执行某种形式的TDD,并且想要编写隔离的测试,则建议不要连接容器来执行测试。您可能希望从单元测试中完全删除该容器。

因此,如果您想测试控制器,则可以执行以下操作:

var sut = new DepartmentsController(new DepartmentRepositoryTestData());

假设您确实希望为IDepartmentRepository拥有一个具体的测试类,而不是使用某种模拟框架。

如果这更多的是集成测试,并且您确实想连接一个容器以测试类之间的交互,那么这将是您的容器注册代码的责任。您应该对测试故事和生产故事分别进行容器注册,以便服务可以根据上下文解析为不同的具体实例。

编辑

我认为您实际上是在问两个问题:一个是关于路由和参数的问题,另一个是关于DI的问题。我将从DI的角度回答。

您说的是:

为了使这种抽象(Controller构造函数的接口arg)具有任何值,必须有多个实现该接口的类,对吗?

您是说接口/抽象仅在有多个实现的情况下有用吗?我认为这是一个见解,但是许多使用DI的人都会创建接口来促进松散耦合,即使只有一个(生产)实现也是如此。通常,第二个或后续实现是模拟的。

这可以是“测试数据”类和“生产数据”类,也可以是“加利福尼亚披萨”类和“纽约披萨”类,或者是全部实现的加利福尼亚,纽约,芝加哥和意大利类IPizzaPie。

但是某个地方的交通警察必须说:“实例化加州阶级”或“实例化纽约阶级”等。

这是我的问题:交通警察(类实例决策者)在哪里/在哪里,我们如何告诉它要通过哪个类?

我认为您在这里寻找的是所谓的“抽象工厂”。您可以注册一个接口的多个实例,然后创建一个工厂,该工厂根据某些条件选择实现。

关于这个主题的好文章:http : //blog.ploeh.dk/2012/03/15/ImplementinganAbstractFactory/

编辑#2

您在上次更新中发布的代码负责为ASP.Net MVC解决正确的控制器。这仅仅是MVC使用DI进行工作所必需的管道。

您正在尝试根据某种上下文返回服务的特定实现。如上文所述,通常使用抽象工厂来完成。您将创建一个工厂接口,并通过构造函数将其注入到控制器中,然后在控制器方法或构造函数中这样调用它:

IDepartmentRepository存储库= _departmentRepoFactory.Create(myContext);

从任何角度看,某些地方的代码都必须请求容器提供基于某种东西(字符串,枚举,整数等)的实现,而这正是抽象工厂的所在。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何连接我的Web API Castle Windsor DI代码的各个部分?

来自分类Dev

如何获取Web API / Castle Windsor来识别控制器?

来自分类Dev

使用Castle Windsor和动态加载的DLL解析控制器

来自分类Dev

Web API请求后需要EF DbContext的Castle Windsor Lifestyle

来自分类Dev

如何告诉Web API / Castle Windsor路由引擎在我的存储库中使用其他数据库实例?

来自分类Dev

使用 Castle Windsor fluent API 注册实现多个接口的组件

来自分类Dev

Castle.Windsor可以使用类型和名称来选择构造函数吗?

来自分类Dev

如何使用 Ninject 将初始化实例传递给 Web API 控制器的构造函数

来自分类Dev

使用 Castle Windsor 在服务类的构造函数中使用参数化构造函数初始化类

来自分类Dev

Web API控制器的构造函数如何调用?

来自分类Dev

Castle.Windsor CollectionResolver和组件订购

来自分类Dev

在安装时使用Windsor访问正在解析的类型

来自分类Dev

WPF ViewModel中的Castle Windsor构造函数注入

来自分类Dev

具有构造函数参数的Castle Windsor安装程序

来自分类Dev

Castle.Windsor使用Dapper实例化错误版本的SqlConnection

来自分类Dev

在控制台应用程序中使用Service Bus和Castle Windsor的WCF Azure托管客户端

来自分类Dev

如何在Castle Windsor中配置此ClientBase类

来自分类Dev

使用Ninject和Web API 2.1注入API控制器时发生InvalidOperationException

来自分类Dev

目标数据库无法与NLog 3.1和Windsor Castle日志记录功能一起使用

来自分类Dev

目标数据库无法与NLog 3.1和Windsor Castle日志记录功能一起使用

来自分类Dev

使用Castle Windsor将具有不同实现的列表的对象作为构造函数参数进行解析

来自分类Dev

如何在nuget库中管理Castle Windsor依赖项

来自分类Dev

使用Castle Windsor在WebAPI中进行依赖注入

来自分类Dev

使用Castle Windsor在WebAPI中进行依赖注入

来自分类Dev

在Windows窗体应用程序中使用Castle Windsor

来自分类Dev

使用 Castle Windsor 在 QueryBus 中查找查询处理程序

来自分类Dev

使用 API 时如何组织 Laravel 控制器

来自分类Dev

Castle Windsor 具体类型解析和属性注入

来自分类Dev

IoC Castle Windsor-没有为此对象定义无参数的构造函数

Related 相关文章

  1. 1

    如何连接我的Web API Castle Windsor DI代码的各个部分?

  2. 2

    如何获取Web API / Castle Windsor来识别控制器?

  3. 3

    使用Castle Windsor和动态加载的DLL解析控制器

  4. 4

    Web API请求后需要EF DbContext的Castle Windsor Lifestyle

  5. 5

    如何告诉Web API / Castle Windsor路由引擎在我的存储库中使用其他数据库实例?

  6. 6

    使用 Castle Windsor fluent API 注册实现多个接口的组件

  7. 7

    Castle.Windsor可以使用类型和名称来选择构造函数吗?

  8. 8

    如何使用 Ninject 将初始化实例传递给 Web API 控制器的构造函数

  9. 9

    使用 Castle Windsor 在服务类的构造函数中使用参数化构造函数初始化类

  10. 10

    Web API控制器的构造函数如何调用?

  11. 11

    Castle.Windsor CollectionResolver和组件订购

  12. 12

    在安装时使用Windsor访问正在解析的类型

  13. 13

    WPF ViewModel中的Castle Windsor构造函数注入

  14. 14

    具有构造函数参数的Castle Windsor安装程序

  15. 15

    Castle.Windsor使用Dapper实例化错误版本的SqlConnection

  16. 16

    在控制台应用程序中使用Service Bus和Castle Windsor的WCF Azure托管客户端

  17. 17

    如何在Castle Windsor中配置此ClientBase类

  18. 18

    使用Ninject和Web API 2.1注入API控制器时发生InvalidOperationException

  19. 19

    目标数据库无法与NLog 3.1和Windsor Castle日志记录功能一起使用

  20. 20

    目标数据库无法与NLog 3.1和Windsor Castle日志记录功能一起使用

  21. 21

    使用Castle Windsor将具有不同实现的列表的对象作为构造函数参数进行解析

  22. 22

    如何在nuget库中管理Castle Windsor依赖项

  23. 23

    使用Castle Windsor在WebAPI中进行依赖注入

  24. 24

    使用Castle Windsor在WebAPI中进行依赖注入

  25. 25

    在Windows窗体应用程序中使用Castle Windsor

  26. 26

    使用 Castle Windsor 在 QueryBus 中查找查询处理程序

  27. 27

    使用 API 时如何组织 Laravel 控制器

  28. 28

    Castle Windsor 具体类型解析和属性注入

  29. 29

    IoC Castle Windsor-没有为此对象定义无参数的构造函数

热门标签

归档