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; } } 
10
  • 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... Commented Sep 21, 2018 at 14:31
  • Not at all, Here not even the constructor parameters are assigned back to the variables Commented Sep 21, 2018 at 14:32
  • 2
    stackoverflow.com/questions/130794/what-is-dependency-injection Commented Sep 21, 2018 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 Commented Sep 21, 2018 at 14:37
  • 1
    Interesting comments. Yes, example 2 is technically dependency injection but it would be better to take interfaces than concrete types. Commented Sep 21, 2018 at 14:38

4 Answers 4

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

Sign up to request clarification or add additional context in comments.

4 Comments

Your answer is incorrect w.r.t the OP question: You are speaking about DIP (Dependency Inversion Principle, the D of SOLID), not about DI (Dependency Injection). The OP second example is indeed following a valid DI design.
@Juh_ I have never seen a description of Dependency Injection that didn't include the use of interfaces/abstractions, in most cases & descriptions its one of 4 required parts. Using SOLID is a means to detail that part of it, not to conflate the two even though they are very similar.
I agree that most of the time, DI comes with DIP. But i is not the same thing and should not be confused (and I think the question is actually meant to make that difference). The same confusion often happens between DI and DI-framework. Personally I strongly believe in DI, who doesn't, but don't like DI-framework (well I really only know spring in java).
Also, DIP abstraction is nice as soon as either (1) the modules are public to outside of a code repo, or (2) if there are at least 2 concrete implementations. Otherwise it's a case of YAGNI i think to abstract/generalize a single use-case. On the other hand, everyone in a team/company following the same principles is more important that personal preferences.
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.

1 Comment

The principle of using abstaction is not about DI (Dependency Injection) but DIP (dependency Inversion Principle). It is two different topics. So yes the OP second example is DI, to which we can propose to add DIP (or not, DIP is good but sometime over used to my experience: if the class is fully private to its project creating an abstraction for only one implementation is a case of YAGNI)
1

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

Comments

-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.

2 Comments

You are talking about an IoC container which is not dependency injection, just a facilitator.
@Crowcoder I concur. A note for clarity: "IoC container" = "DI framework" = a framework (so IoC) that instantiate DI components for you. But the components can have a DI design without the framework. Most people speaking about DI usually do it with a dedicated framework, which leads to confusion.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.