Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency Injection: what do you lose when instantiating concrete classes in parameterless constructor

Generally speaking, my dependencies are abstracted to interfaces, but I will only be using one concrete implementation during non-testing use. For example, were I to write a FooService:

public class FooService : IFooService
{
    private readonly IBarDependency _barDependency;

    public FooService(IBarDependency barDependency)
    {
        this._barDependency = barDependency;
    }

    public FooService() : this (new BarDependency())
    {
        // nothing to do here
    }

    . . . // code goes here
}

Now purists tend to gasp in horror, because I instantiated a concrete class in the parameterless constructor. I have, in the past, shrugged this off, because I know the only time I will not be using the concrete class is when I am unit testing and mocking dependencies.

While it does couple the FooService class to the BarDependency class, it's not a tight coupling; these classes and interfaces also exist in the same assembly, so it doesn't seem to me like I'm losing a whole lot here, or painting myself into a corner. I can still easily test the FooService class without getting unmanageable code, just by using the constructor that allows me to pass in mocked interfaces.

So the question is: what is actually at risk here? What am I losing with this sort of pattern that is worth adding an IoC container?

like image 390
Jeremy Holovacs Avatar asked Aug 05 '15 14:08

Jeremy Holovacs


2 Answers

Lifetime management, for example. Maybe you use BarDependency throughout your code and only want one instance to be alive. You can't do this if every user creates their own instances.

You also have to find all usages of new BarDependency() if you ever want to replace it with new NewBarDependency().

A container fixes both problems for you, as then you configure the instantiation and lifecycle of objects in one method, namely where you set up your container.

like image 65
CodeCaster Avatar answered Sep 23 '22 14:09

CodeCaster


It depends, but if the FooService needs to be accessed by some other developer, the dependency to BarDependency will be basically hidden. In my opinion not only mocking and testing is the reason for using dependency injection, but also a clear indication what is used by certaing classes, and what they are need to work properly. And maybe I'm to much purist, but when such pattern is ok, then it's easily to go further and end up with a totally tightly coupled and hard maintanable code.

like image 43
alek kowalczyk Avatar answered Sep 23 '22 14:09

alek kowalczyk