Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
225 views
in Technique[技术] by (71.8m points)

c# - Implementing Dependency injection static methods

In this old code I am trying to update , they implemented dependency injection like this:

public class Program
{
    private IProgramRepository programRepository;

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

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

now in this program class all methods are static, so all of the static methods all actually have 2 methods like this:

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

Now I've read this among other things about implementing DI:

This is not dependency injection at all. This actually clearly violate the dependency inversion principle. The principle say that "High level module should not depend upon the low level module, both should depend on abstraction. Details should depends upon abstraction". In above code Product.cs itself create EN_Program object. So it directly depends on IProgramRepository implementation (EN_Program). If in future another implementation comes of IProgramRepository interface then Product.cs code itself need to change. So it is probed that it is not proper way to do.

It looks like the old developers wanted to implement DI just starting with the helper classes (Program.cs) with nothing injected into the controllers.

Am I correct in assuming that this old code was not written correctly ? Is it necessary when implementing DI that everything from the controller to the back end have injections?

ex. The controller would need to be injected with an Interface that the helper class uses (Program.cs) - then Program.cs is injected with an interface that the repository uses

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The comment is incorrect. It talks about Dependency Injection pattern, but it quotes the Dependency Inversion Principle. The overloaded constructor is an implementation of the Dependency Injection pattern, and the default constructor is an implementation of the Poor Man's Dependency Injection anti-pattern.

Although the overloaded constructor practices the Dependency Injection pattern, the default constructor does not and does in fact violates the Dependency Inversion Principle. Because of the reasons quoted.

So you're absolutely practicing Dependency Injection, but you are also practicing Poor Man's Dependency Injection which is bad for a lot of reasons. For instance:

  • Your code takes a direct dependency on a low level component disallowing you to ship them separately.
  • The direct dependency makes it harder to swap implementations, which is something that is very common to do when you add cross-cutting concerns (using decorators or interceptors) . You don't want to go through the whole application to change all constructors just to wrap EN_Program instances with a decorator or interceptor.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...