Why is the link with new keyword dependencies considered bad?

I've been using Dependency Injection for a while now, and now I want to talk about IoC and DI with a group of new developers. I remember explaining this to one guy in person and he asked me:

"Why not just use:

private IMyInterface _instance = new MyImplementaion();

      

instead of going through all the DI alarm. "

My answer is "Testing modules requires mocks and stubs." - but we don't write unit tests at my company so that he doesn't convince him. I told him that the concrete implementation is bad as you are closely related to one implementation. Changing one component will change the other.

Can you provide an example for such code? Can you give me more reasons why this code is bad?

It seems so obvious to me that it's hard for me to explain it :-)

+3


source to share


1 answer


Problem with next link

public class MyClass
{
    private IMyInterface _instance = new MyImplementation();
    ...

      

Means that at any time it MyClass

is created (either directly or via an IoC container) that it will always immediately create a specific one MyImplementation

and associate its dependency _instance

with that specific implementation. In turn, it is likely that it MyImplementation

has other dependencies that are also linked in this way.

The advantages of decoupling such classes, which MyClass

only depends on the interfaces to its dependencies, and not on specific implementations of the dependencies (i.e. on D SOLID ):

  • for unit testing. As you mentioned, for testing MyClass

    in isolation, with dependencies new'ed

    , you need to do nasty things like Moles / Fakes

    mocking a hard-wired dependency MyImplementation

    .

  • for substitution - by connecting only to the interface, you can now change various concrete implementations IMyInterface

    (for example, via the strategy pattern) without changing the code in MyClass

    .

  • in order to make the dependencies clear and obvious on your system, as a dependency IMyInterface

    may have additional dependencies that need to be resolved (and may also need tweaking). If MyClass

    hides an internal dependency IMyInterface

    , the caller doesn't see what the dependency is MyClass

    . While this was common in classic 1990 OO (i.e. Encapsulation + Composition), it can overshadow the implementation as deploying all dependencies still needs to be done. However, when the connection is done at the interface level (i.e. MyClass users will only do this through IMyClass

    ), the connection visibility interface IMyClass

    will hide the dependency on again IMyInterface

    , since the constructors are not visible on the interface).

  • for configurable dependency lifetime management. By entering IMyInterface

    instead of the new one MyImplementation

    , you allow additional configuration options with regard to managing the object's lifetime MyImplementation

    . When the initial solid creation MyImplementation

    was completed MyClass

    , it actually took charge of the MyImplementation

    lifespan. By leaving this in the IoC container, you can now play with other MyImplementation

    lifespan options that might be more efficient, for example. if the instances MyImplementation

    are thread safe, you can, for example, select an instance for multiple instances MyClass

    .



In a nutshell, this is how I believe the refactoring should look suitable for IoC constructor dependency injection:

public class MyClass
{
    // Coupled onto the the interface. Dependency can be mocked, and substituted
    private readonly IMyInterface _instance;

    public MyClass(IMyInterface instance)
    {
       _instance = instance;
    }
    ...

      

Bootstrapping the IoC container will define the WHICH implementation IMyInterface

to be linked and will also define the lifetime of the dependency, for example. in Ninject:

 Bind<IMyInterface>()
     .To<SomeConcreteDependency>() // Which implements IMyInterface
     .InSingletonScope();

      

+2


source







All Articles