5

Is this dependency injection if I change the below code

class Needer
{
    Needed obj;
    AnotherNeeded obj2;

    public Needer()
    {
        obj = new Neede();
        obj2 = new AnotherNeede();
    }
}

To this code

class Needer
{
    Needed obj;
    AnotherNeeded obj2;

    public Needer(Needed param1, AnotherNeeded param2)
    {
        obj = param1;
        obj2 = param2;
    }
}
maccettura
  • 9,653
  • 3
  • 20
  • 28
ITExpert
  • 183
  • 1
  • 8
  • 6
    Neither of those examples are dependency injection. You should use interfaces/abstractions as parameters in your constructor then just assign those parameter values to your fields/properties. The point of dependency injection is to _never_ new up a dependency manually. Just look at your second example, `param1` and `param2` never go anywhere, you completely ignore them... – maccettura Sep 21 '18 at 14:31
  • Not at all, Here not even the constructor parameters are assigned back to the variables – Hary Sep 21 '18 at 14:32
  • 2
    https://stackoverflow.com/questions/130794/what-is-dependency-injection – Hary Sep 21 '18 at 14:33
  • @maccettura and mbharanidharan88! guys please hold on... that was a copy paste which was never intended to so. I have updated my question with the rightly worded code – ITExpert Sep 21 '18 at 14:37
  • 1
    Interesting comments. Yes, example 2 is technically dependency injection but it would be better to take interfaces than concrete types. – Crowcoder Sep 21 '18 at 14:38
  • @Crowcoder the question was edited after the initial comments – maccettura Sep 21 '18 at 14:40
  • This is a good demo - http://www.tutorialsteacher.com/ioc/dependency-injection – Brian Rodgers Sep 21 '18 at 14:46
  • @maccettura perhaps you can delete your initial comment as it is irrelevant now and misleading as well. Actually your comment was posted within 60 seconds of my question and by then my page was not fully refreshed. – ITExpert Sep 21 '18 at 14:49
  • @ITExpert its still partially relevant since you are still not using abstractions – maccettura Sep 21 '18 at 14:50
  • @maccettura perhaps your very last line, starting from _Just look at.._! – ITExpert Sep 23 '18 at 00:52

4 Answers4

3

The first option is tightly coupling the dependent class to its dependencies by newing them up in the constructor. This makes testing that class in isolation very difficult (, but not impossible).

The second option follows what is sometimes referred to as the The Explicit Dependencies Principle

The Explicit Dependencies Principle states:

Methods and classes should explicitly require (typically through method parameters or constructor parameters) any collaborating objects they need in order to function correctly.

The said, it is also usually advised to have dependent classes depend on abstractions and not concretions or implementation concerns.

So assuming that those needed classes have interfaces/abstractions that they derive from it would look like

class Needer {
    private readonly INeeded obj;
    private readonly IAnotherNeeded obj2;

    public Needer(INeeded param1, IAnotherNeeded param2) {
        obj = param1;
        obj2 = param2;
    }

    //...
}

The allows more flexibility with the dependent class as it decouples it from implementation concerns, which allows the class to be tested in isolation easier.

Nkosi
  • 191,971
  • 29
  • 311
  • 378
3

Robert C. Martin described Dependency Injecton in his SOLID design proposal. It basically states that:

  • High-level modules should not depend on low-level modules. Both should depend on abstractions.

  • Abstractions should not depend on details. Details should depend on abstractions.

Notice a word being used a lot in that description? "Abstraction".

You get part of the problem right in your second example, you no longer manually instantiate instances of the class, you instead pass them through the constructor. This leads into a new potential problem though, what if you need a different implementation of some class (e.g a "mock" and "real" services). If your constructor took the abstractions instead of the concretes you could change the implementations in your IoC configuration.

Any sort of service or functional class should typically have an abstraction behind it. This allows your code to be more flexible, extendable and easier to maintain. So to make your second example use true dependency injection:

class Needer
{
    public INeeded obj { get; set; }
    public IAnotherNeeded obj2 { get; set; }

    public Needer(INeeded param1, IAnotherNeeded param2)
    {
        obj = param1;
        obj2 = param2;
    }
}

Now you can have all sorts of implementations:

public class MockNeeded : INeeded

public class ApiNeeded : INeeded

etc, etc

maccettura
  • 9,653
  • 3
  • 20
  • 28
0

the second example is DI (dependency injection). DI is usually used with IoC (Inversion of Control) which takes care of creating the dependencies for you based on some configuration. have a look at autofac. autofac

mojobec
  • 71
  • 1
  • 6
-1

The injection doesn't happen on it's own.

Instead, there should be some kind of a factory that generates objects and uses a dependency resolver, if available.

For instance, an MVC.NET framework is that kind of a "factory", when it creates an instance of, let's say, a Controller class, it uses the DependencyResolver.Current property to populate the constructor arguments.

AgentFire
  • 8,224
  • 6
  • 39
  • 84