【问题标题】:Implementing Dependency injection static methods实现依赖注入静态方法
【发布时间】:2013-04-29 15:14:06
【问题描述】:

在我尝试更新的旧代码中,他们实现了这样的依赖注入:

public class Program
{
    private IProgramRepository programRepository;

     public Program(IProgramRepository repository)
        {
             this.programRepository = repository;
        }

     public Program() : this(new EN_Program()) { }

现在这个程序类中的所有方法都是静态的,所以所有的静态方法实际上都有两个这样的方法:

    public static List<Program> GetProgramsByUser(int userId)
    {
        return GetProgramsByUser(userId, GetDefaultRepository());
    }
    private static List<Program> GetProgramsByUser(int userId, IProgramRepository repo)
    {
        return repo.GetProgramsByUser(userId);
    }

现在我已经阅读了有关实施 DI 的其他内容:

这根本不是依赖注入。这实际上明显违反 依赖倒置原则。原则说“高水平 模块不应该依赖于低级模块,两者都应该依赖 关于抽象。细节应该取决于抽象”。在上面 代码 Product.cs 本身创建 EN_Program 对象。所以直接 取决于 IProgramRepository 实现 (EN_Program)。如果将来 另一个实现来自 IProgramRepository 接口,然后是 Product.cs 代码本身需要更改。所以被探查是不是正确的方式 去做。

看起来老开发者想要实现 DI,只是从帮助类 (Program.cs) 开始,而没有向控制器注入任何内容。

我是否正确假设这段旧代码没有正确编写?在实现 DI 时是否有必要从控制器到后端的所有内容都进行注入?

例如。控制器需要注入帮助类使用的接口 (Program.cs) - 然后 Program.cs 注入存储库使用的接口

【问题讨论】:

    标签: c# asp.net-mvc dependency-injection


    【解决方案1】:

    评论不正确。它谈到了依赖注入模式,但它引用了Dependency Inversion Principle。重载的构造函数是依赖注入pattern的实现,默认构造函数是Poor Man's Dependency Injection anti-pattern的实现。

    虽然重载的构造函数实践了依赖注入模式,但默认构造函数并没有而且实际上违反了依赖倒置原则。由于引用的原因。

    所以你绝对是在练习依赖注入,但你也在练习穷人的依赖注入,这有很多原因是不好的。例如:

    • 您的代码直接依赖于低级组件,不允许您单独发布它们。
    • 直接依赖使交换实现变得更加困难,当您添加横切关注点(使用装饰器或拦截器)时,这是很常见的事情。您不想通过整个应用程序来更改所有构造函数,只是为了用装饰器或拦截器包装 EN_Program 实例。

    【讨论】:

    • @Scott Selby 添加到 @Steven 的出色写作中,如果您想避免每次想要获取 Program 实例(或始终通过 DI 容器获取 Program 实例)时都提供依赖项),您可以使用Service Locator。如果您有很多类,每个类都依赖于某个存储库,这很有意义;构造函数注入通过使这种依赖显式化没有任何附加价值,因为它已经是一个明显的依赖。
    【解决方案2】:

    第一种方法依赖于工厂方法(我希望如此)。在这个工厂方法中创建了一个IProgramRepository。这个函数不依赖于任何东西,只依赖于工厂方法本身。

    public static List<Program> GetProgramsByUser(int userId)
    {
        return GetProgramsByUser(userId, GetDefaultRepository());
    }
    

    第二种方法也不依赖于其他类。 depencing 在参数中“给定”。

    private static List<Program> GetProgramsByUser(int userId, IProgramRepository repo)
    {
        return repo.GetProgramsByUser(userId);
    }
    

    编辑

    官方称依赖注入 (DI) 是控制反转 (IoC) 的一个子集,这些术语有时会混淆。也许官方你的代码并没有真正遵循 DI 的规则,但它肯定是 IoC!

    【讨论】:

      猜你喜欢
      • 2015-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多