15

During a code review I have started having a bit of a dilemma as to whether use dependency injection or not. I would like to hear your thoughts, because this is kind of an ongoing theme and would help in the future code reviews as well.

Before I start I want to say that from my knowledge DI is mostly used for dependency management and better, much easier unit testing (correct me if I am wrong please).

Now here is the scenario:

This is the class that will be used as a dependency only once and probably for good. Meaning it will stay that way for a while and no other class will be using it.

Reason being is because it is a refactoring of some legacy code and there was not much to be done but to separate it into another class, at least as a first good step, for following the SRP.

Also, another thing is that the hypothetical doSomethingImportant() hits the database.

public SomeClass
{
   public Object doSomethingImportant()
   {
      ...
   }
}

Based on that information do you think it is okay to new up the dependency in the other class as opposed to using DI since:

Dependency management argument kind of falls off since it is only going to be used once.

&

Unit testing also falls off since I would rather do an integration or acceptance test to see how the method is interacting with the database in a real-life application.

public SomeOtherClass
{
   private readonly SomeClass _someClass = new SomeClass();

   public Object doSomethingImportantUsingDependency()
   {
      ...
   }
}

I was personally inclined towards doing DI because it is considered good practice, but for a second there it felt like I was blindingly following the rules and not thinking it over since there are always exceptions to the rule.

What are your thoughts on this? I would love to hear.

PS: I don't think this is a generic "when should I use DI" question because it is very specific to this particular situation when unit tests are of no use and the class is going to be used only once so there is no need to centralize it for dependency management (even though it is good practice in general).

Avetis Ghukasyan
  • 1,534
  • 3
  • 14
  • 26

4 Answers4

15

In C# it is trivial to provide optional dependency injection without coupling yourself to your dependency too tightly:

public class SomeOtherClass {
    private readonly ISomeClass _someClass;

    public SomeOtherClass(ISomeClass dependency = null) {
        _someClass = dependency ?? new SomeClass();
    }
}

(or you can make the constructors explicit if your company dislikes default params)

In my experience, "oh we'll never need another one" is naive. Business changes. Technology changes. Make dependencies flexible.

And this sort of thing strikes the right balance between usability (yes, you'll almost always use the common/default one) and flexibility (but the ctor is there if you need it) - all with a nice simple line of code, while also providing some semblance of error correcting robustness. It's so trivial and clearly beneficial, there's no reason not to do it for the simple/straight-forward case.

Telastyn
  • 110,259
11

There's a development principle along the lines of DRY and SOLID called YAGNI that is designed to help streamline your development efforts in getting things done and not getting paralysed with indecision over what to do.

If you later find that you need to enhance your class, then you will. YAGNI says not to worry so much over it now 'cos you probably won't need to spend that extra effort. Get it done, come back to it if you really need to.

Some say its the opposite of SOLID but really its all about trading off all the factors involved in development, you don't have infinite time or resources (and 'perfect' code never is IMHO).

So here, you say it doesn't need DI complexity... so there's your answer. Don't put it in. Move on to all the other things you have to do.

gbjbaanb
  • 48,749
  • 7
  • 106
  • 173
5

If you do not apply DI as long as you do not really need it (not even for unit testing), nothing bad will happen. The code does not become error prone, "overly complicated", or hard to maintain. And if you decide to refactor the dependency out later, it will most probably not be much more effort than doing it now. That's a case where the YAGNI principle applies.

However, what you should check is if you are sure you really do not want to be able to unit test SomeOtherClass in isolation from SomeClass, and if the imposed dependency on the assemblies where SomeOtherClass and SomeClass live will not become a problem. If you are 100% sure that the answer to the former questions is "yes", then you can ignore DI.

Doc Brown
  • 218,378
0

The answer like most things is "it depends".

If you want to unit-test the functionality in doSomethingImportantUsingDependency, then you will need to be able to inject the dependency.

However, if all that doSomethingImportantUsingDependency does is some property mapping from the result of your database call, then it would be pragmatic to not bother.

If some other class depends on SomeOtherClass then you can always inject that class instead.

Matthew
  • 2,026