在我试图更新的旧代码中,他们实现了这样的依赖注入:
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时,从控制器到后端都有注入是否必要?
交货。控制器需要被注入helper类使用的接口(Program.cs)——然后Program.cs被注入存储库使用的接口
注释不正确。它讨论了依赖注入模式,但它引用了依赖倒置原则。重载构造函数是依赖注入模式的实现,默认构造函数是穷人依赖注入反模式的实现。
虽然重载构造函数采用依赖注入模式,但默认构造函数没有,而且实际上违反了依赖倒置原则。
所以你绝对是在实践依赖注入,但你也在实践穷人的依赖注入,这有很多不好的原因。例如:
- 你的代码直接依赖于底层组件,不允许你单独发布它们。
- 直接依赖使交换实现变得更加困难,这是在添加横切关注点(使用装饰器或拦截器)时非常常见的事情。你不希望在整个应用程序中修改所有的构造函数,只是为了用一个装饰器或拦截器包装
EN_Program
实例。
第一个方法依赖于一个工厂方法(我希望)。在这个工厂方法中创建了一个IProgramRepository
。这个函数只依赖于工厂方法本身。
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)是控制反转(IoC)的一个子集,这些术语有时会混淆。也许你的代码并没有真正遵循DI的规则,但它确实是IoC !