dependency injection in C #

S Fattahi
4 min readNov 17, 2020

One of the topics in C # training is dependency injection. In this article, we want to discuss dependency injection in C #. But before that, you should be familiar with two concepts:
Dependency Inversion Principle or DIP for short
Inversion of Controls, or IoC for short

Dependency Inversion Principle:

One of the principles of objectivism was invented by Mr. Robert Martin, known as Uncle Bob.
The principle of dependency inversion is a software design principle that helps us to produce a software with low communication strength (Loosely Coupled). Simply put, high-level modules should not be dependent on low-level modules. Rather, both must be dependent on an interface, and abstraction must not be dependent on details, but details must be dependent on abstraction. (Abstraction is an overview of an object. For example, when we say table, what is in our mind is a general form, but when we say dining table, we specify exactly what kind of table it is.)

Inversion of Control:

As you can see, the principle of dependency inversion tells us what the dependence of two modules should be. To do this we need to use the IoC or control inversion. IoC is a fully functional method by which it connects high-level modules to abstractions instead of relying on low-level modules.
Let me give you an example. Suppose you are driving on your way to work, which means you are in control of your car. Now what does the IoC principle say? This principle suggests reversing control, that is, you take a taxi and let someone else drive instead of driving yourself. In this case, the control is reversed from you to the taxi driver and you no longer have to drive yourself and in order to be able to focus on your main job, you entrust this task to the taxi driver.

Definition of dependency injection in C #:

Dependency Injection is a pattern and design pattern whose main purpose is to eliminate the dependencies between two classes using an interface. We have two terms in injecting dependencies.
1. loosely coupled: there is the least dependency between the two classes
2. tight coupled: there is the most dependency between the two classes
Therefore, we must design our program and software in such a way that the strength between the two classes is as weak as possible. Because when two classes are highly interdependent or so-called intertwined, they greatly reduce the flexibility of the software.

Example:

Now we want to tell you the story of C # dependency injection with an interesting example.
Suppose we want to write a game called Ninja in which brave warriors fight their enemies to gain their honor, but first we must provide a suitable weapon for our warriors. A sword that we call Sword and we start: this class has a hit method and every time we call it, it will be hit and our target will be halved! Well, this is a weapon.

class Sword

{

public void Hit(string target)

{

Console.WriteLine(“Chopped {0} clean in half”, target);

}

}

It’s time to build a samurai to attack the enemy. But our samurai class must have a method of attack that kills the enemy with its sword when we summon it.

class Samurai

{

readonly Sword sword;

public Samurai()

{

this.sword = new Sword();

}

public void Attack(string target)

{

this.sword.Hit(target);

}

}

Now it is enough to make a samurai and fight!

class Program

{

public static void Main()

{

var warrior = new Samurai();

warrior.Attack(“the evildoers”);

}

}

In this code, we fight the evildoers and cut him in half with a sword.
But suppose we want our samurai to fight with a weapon other than a sword! For example, with shuriken, the winning blade looks like a star
In this case, we have to change the samurai class completely, because in the samurai class, we only used the sword class. So every time our ninja wants to fight with a new weapon, we have to change the samurai class and thus Tightly Coupled occurs, ie the dependence of the samurai class on the sword class. Naturally, we do not like these kinds of dependencies. Because it forces us to change our code. To eliminate these dependencies, we use interfaces. Let’s create an interface called weapon:

interface IWeapon

{

void Hit(string target);

}

Now connect the sword class to this interface or so-called Implement it:

class Sword : IWeapon

{

public void Hit(string target)

{

Console.WriteLine(“Chopped {0} clean in half”, target);

}

}

Now we change the samurai to use a weapon instead of a sword:

class Samurai

{

readonly IWeapon weapon;

public Samurai()

{

this.weapon = new Sword();

}

public void Attack(string target)

{

this.weapon.Hit(target);

}

}

Now our samurai can use different weapons. Only one place does not work. We still use the sword in the samurai class:
this.weapon = new Sword ();
So we have to make the samurai class a little better. It is enough to give the desired weapon to the samurai through the constructor:

class Samurai

{

readonly IWeapon weapon;

public Samurai(IWeapon weapon)

{

this.weapon = weapon;

}

public void Attack(string target)

{

this.weapon.Hit(target);

}

}

Now we change the samurai to use a weapon instead of a sword:

class Shuriken : IWeapon

{

public void Hit(string target)

{

Console.WriteLine(“Pierced {0}’s armor”, target);

}

}

Now we build a samurai army with different weapons and attack the evildoers. Are you ready?

class Program

{

public static void Main()

{

var warrior1 = new Samurai(new Shuriken());

var warrior2 = new Samurai(new Sword());

warrior1.Attack(“the evildoers”);

warrior2.Attack(“the evildoers”);

}

}

Well, friends, I hope you are satisfied with the article.

--

--

S Fattahi

Web designer Isolate music and writing Bachelor of Computer Software