C# 实现依赖注入静态方法

C# 实现依赖注入静态方法,c#,asp.net-mvc,dependency-injection,C#,Asp.net Mvc,Dependency Injection,在我试图更新的这段旧代码中,他们实现了如下依赖项注入: public class Program { private IProgramRepository programRepository; public Program(IProgramRepository repository) { this.programRepository = repository; } public Program() : th

在我试图更新的这段旧代码中,他们实现了如下依赖项注入:

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);
    }
现在在这个程序类中,所有的方法都是静态的,所以所有的静态方法实际上都有两个这样的方法:

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);
    }
公共静态列表GetProgramsByUser(int userId)
{
返回GetProgramsByUser(userId,GetDefaultRepository());
}
私有静态列表GetProgramsByUser(int userId,IProgramRepository repo)
{
返回repo.getProgramsByser(userId);
}
现在,我已经阅读了关于实现DI的其他内容:

这根本不是依赖注入。这实际上显然违反了法律 依赖倒置原理。原则说"高层次", 模块不应依赖于低电平模块,两者都应依赖于 关于抽象。细节应该取决于抽象”。在上面 代码Product.cs本身创建EN_程序对象。所以它直接 取决于IProgramRepository实现(EN_程序)。如果将来 另一个实现是IProgramRepository接口,然后是Product.cs 代码本身需要更改。因此,有人认为这是一种不恰当的方法 去做

看起来老的开发人员想要实现DI,只是从helper类(Program.cs)开始,而不向控制器注入任何东西

我认为这段旧代码写得不正确,对吗?在实现DI时,从控制器到后端的所有东西都有注入是必要的吗


例如,控制器需要注入helper类使用的接口(Program.cs)-然后Program.cs注入存储库使用的接口。第一种方法取决于工厂方法(我希望如此)。在这个工厂方法中,创建了一个
IProgramRepository
。此函数只依赖于工厂方法本身

public static List<Program> GetProgramsByUser(int userId)
{
    return GetProgramsByUser(userId, GetDefaultRepository());
}
公共静态列表GetProgramsByUser(int userId)
{
返回GetProgramsByUser(userId,GetDefaultRepository());
}
第二种方法也不依赖于其他类。在参数中“给定”了依赖关系

private static List<Program> GetProgramsByUser(int userId, IProgramRepository repo)
{
    return repo.GetProgramsByUser(userId);
}
private static List GetProgramsByUser(int userId,iprogram存储库repo)
{
返回repo.getProgramsByser(userId);
}
编辑


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

评论不正确。它谈到依赖注入模式,但引用了。重载构造函数是依赖项注入模式的实现,而默认构造函数是依赖项注入模式的实现

尽管重载构造函数实践依赖项注入模式,但默认构造函数没有而且实际上违反了依赖项反转原则。因为引用的理由

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

  • 您的代码直接依赖于低级组件,不允许您单独发布它们
  • 直接依赖性使交换实现变得更加困难,这在添加横切关注点(使用装饰器或拦截器)时非常常见。您不希望遍历整个应用程序来更改所有构造函数,而只是将
    EN_程序
    实例包装为decorator或interceptor

@Scott Selby在@Steven的伟大著作中补充道,如果您希望避免每次获取
程序
实例(或总是通过DI容器获取
程序
实例)时都提供依赖性,那么可以使用。如果您有很多类,每个类都依赖于某个存储库,那么这很有意义;构造函数注入通过使这种依赖关系显式化没有任何附加值,因为它已经是一种明显的依赖关系。