Dependency Injection

Dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies.

Dependency injection is a programming technique that makes a class independent of its dependencies. It achieves that by decoupling the usage of an object from its creation. This helps you to follow SOLID’s dependency inversion and single responsibility principles.

For dependency inject we need 4 things in our hand:

  • The service.

  • An interface implemented by the service.

  • The client that uses the service via interface.

  • The injector which creates a service instance and injects it into the client.

We need interface so that we can take advantage of different version or variations of implementations and that can be injected into client.

For example:

Let's say we have one simple interface called IBroadcast with just one method called NotifyAll(). We want one or many classes (services) to implement this interface and define what exactly NotifyAll() method should do.

You can have EmailBroadcaster or TextBroadcaster classes implementing IBroadcast. Where EmailBroadcaster sends out emails while TextBroadcaster sends out text messages to phone numbers.

Now let's say injector can can create instance of EmailBroadcaster or TextBroadcaster

IBroadcast broadcastHandler = EmailBroadcaster()

or

IBroadcast broadcastHandler = TextBroadcaster()

and pass broadcastHandler to client. Client just needs to execute NotifyAll() and underlying implementation will take care of purpose.

Interesting things is, for writing unit test on NotifyAll() is easy job now.

Do you want to use real production classes to test it daily via unit tests? No way... Right?

So inject a fake service which implements IBroadcast.

So do you think interface is playing important role?

If you think it is not then just imagine injecting concrete instances of objects instead of interface instances. There you are creating tight coupling with respective implementations. More code, more maintenance , not extendable. Change in one triggers change in other.

Simply put, interface removes the dependency between the client and the service implementation.

Last part is injector -

You can manually inject a service by creating its instance and then injecting into a service through constructors. Obviously very simple because service class takes these few parameters (dependencies) and initializes.

But you can also use IoC Container (a.k.a. DI Container). It is a framework for implementing automatic dependency injection. It manages object creating and its life time and also injects dependencies to the class.

More about IoC containers are covered in IoC Containers