Programming

Dependency Injection – IoC

In this post, you will learn what Dependency Injection is, why it would be useful and how to implement it.

The examples will be written in C# and published into my GitHub.

I chose C# because it’s a fairly popular language and will (hopefully) be understood by anyone from any language.

Let’s get right in.

What is Dependency Injection

Dependency Injection is a complex-sounding name for a pretty simple concept.

It’s a programming technique (sometimes called a design pattern) that helps implement Inversion of Control.

It is used to pass a dependency (the class to be used) onto the class we’re writing, promoting loose coupling and allowing said dependency to be changed at runtime, if need be. (for instance by user input)

Suppose we have a class that looks like this:

Example with no Dependency Injection

You can clearly see that this isn’t dependency “injectable”, since when calling this method, we can’t specify which payment method to use, we’re forced to use Credit Card.

What would be an example of Dependency Injection then?

Example of Dependency Injection

In that case, we can change which payment method the method will use at runtime, by passing an implementation of IPaymentMethod via parameter.

We could call it like this:

Using the PersonExample

Frameworks for this

You have a ton of frameworks for Dependency Injection, for every language.

Such as, in the JVM world, you have Spring and Quarkus. (to which I wrote a post on)

Why would we want this?

Easier to unit test

By allowing us to change the dependency from the “outside” (when calling it), we can change its dependency to a mocked one.

Alternative to the Singleton pattern

Static is usually seen as evil, and Singleton is no exception, being regarded as an anti-pattern.

Bear in mind that not all cases are equal, there are some reasonable uses of static such as a mapping function.

Easier to maintain

Suppose you are using that first PersonExample in 50 different places, now imagine that you want to introduce a different IPaymentMethod, but only in 20 of those… How would you do that?

Using Dependency Injection, it’s way more manageable, you would still need to change the code in 20 different places but it’s not as bad as when not using it. (unless you use a framework for it, in which case is just 1 change)

If you were doing as the first, non-DI example then you would probably need to pass a boolean or enum that would determine which payment method to use, in all those places, yikes!

Decoupling from the class and its dependency

Low coupling prevents our code from knowing too much of the internals of a component, meaning that, if such component changes, it is less likely to break code that depends on it.

With dependency injection, you ask for an abstraction, and the DI framework gives you the implementation, under the hood.
The “public API” doesn’t usually change, except on breaking changes, unlike the implementations where this is more common.

Field vs Constructor injection

There are 3 ways of injection a dependency:

  • Field
    • setting a variable to the dependency directly, or through injection (var service = ServiceA() / @Inject ServiceA service)
    • avoid this at all costs, since then you can’t inject a mock in a unit test.
  • Parameter
    • used for dependencies that are momentary for the method
    • this is the one I showed above
  • Setter
    • having a setter method that sets the dependency variable
    • used to change the dependency in runtime
  • Constructor
    • passing via constructor
    • used when the dependency won’t change throughout the class’ lifetime

Closing thoughts

You can find the code on my GitHub: https://github.com/LegendL3n/Inversion-of-Control.

Find a framework with Dependency Injection for your language, to avoid having to handle dependencies on your own.

See you at the next one! 😉

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s