c# - 依赖注入(inject)问题——如何清理我的实现?

标签 c# .net unit-testing dependency-injection code-cleanup

我正在使用依赖注入(inject)来模拟类,以便对依赖于它们的其他类进行单元测试:

class Foo : IFoo
{
    // production code
}

class MockFoo : IFoo
{
    // mock so other classes that depend on Foo can be unit tested
}

class Bar
{
    public DoSomething()
    {
        var barValue = 20;
        // use dependency injection to get Foo instance.
        DependencyInjection.Instance.Foo.ExampleMethod(barValue);
    }
}

但是,设置我的依赖注入(inject)类变得笨拙、复杂且复杂:

public class DependencyInjection
{
    public Setup()
    {
        this.Foo = new Foo();
        this.Bar = new Bar("example constructor string");
        this.Bat = new Bat(123,234);
        // for every single class in my application!
    }
}

(为清楚起见进行了简化,但您可以想象具有数十个类及其构造函数的真实实现)。

还有一些其他问题:

  • DependencyInjection 及其每个类实例都是巨大的全局 变量 在我的应用程序中传递。
  • 我同时初始化我所有的类。
  • 我必须提供一个接口(interface) 对于我为单元测试编写的每个类——我允许进行单元测试 决定我的程序的设计(我写的大部分类(class) 如果不是的话,将是没有接口(interface)的具体实现 这个约束)。

将不胜感激有关如何解决这些问题的建议!

最佳答案

使用 DI 并不意味着您应该突然停止对代码进行解耦。绝不应该使用全局变量来传递您的实现。

当你创建一个需要解决某部分功能的类时,你应该通过构造函数传递所有“外部”依赖:

class Bar
{
    private readonly IFoo _foo;
    public Bar(IFoo foo)
    {
        _foo = foo;
    }

    public DoSomething()
    {
        _foo.ExampleMethod(20)
    }
}

DI 的最佳实践是在应用程序的开头 (composition root) 使用它来获取外部实现,然后像没有 DI 一样传递实现。

底线是:您不需要注入(inject) IFoo 来测试Bar - 只需在您的测试方法中模拟它,你就完成了。仅将 DI 用于您希望可配置的应用程序的重要 block (例如,选择具体的数据层)。

关于c# - 依赖注入(inject)问题——如何清理我的实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13111775/

相关文章:

c# - 将日期格式化为特定格式

c# - 使用 DbContext 在一个文件中生成 POCO 类

unit-testing - 使用 Google App Engine `files` api 测试功能

java - 使用 powermockito 模拟静态类

c# - 日期时间本地化。任何标准/最佳实践

c# - 你如何在 CaSTLe MVC (Monorail) 中获取用户的 IP 地址?

c# - 这些比较应该返回什么?

java - 如何对 Spring ResourceHandlerRegistry 服务的静态资源进行单元测试

c# - 如何反射(reflect) T 以构建查询的表达式树?

c# - HTTP 错误 404.13 - asp.net core 2.0