Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency injection in C#

I am learning the constructor injection from this source https://softwareengineering.stackexchange.com/questions/177649/what-is-constructor-injection

I am happy that I am able to understand it. However, I have a basic doubt related to interface and class and injection of interface in the constructor.

In specific, I am not able to understand how we inject the interface without creating the object Sword as in first snippet.

class Samurai
{
    readonly IWeapon weapon;
    public Samurai() 
    {
        this.weapon = new Sword();
    }
    public void Attack(string target) 
    {
        this.weapon.Hit(target);
    }
}

In this below snippet, they claim it does the same thing as above code, however, with loose coupling.

class Samurai
{
    readonly IWeapon weapon;
    public Samurai(IWeapon weapon) 
    {
        this.weapon = weapon;
    }
    public void Attack(string target) 
    {
        this.weapon.Hit(target);
    }
}

Can someone please help me understand why we are not creating object of Sword using "new" keyword in the second snippet and how it functions without that? Are the above two snippets same? And also, how is this a lose coupling?

like image 582
Jasmine Avatar asked Mar 22 '23 17:03

Jasmine


1 Answers

Passing in an implementation of IWeapon allows you to have as many versions of a weapon as you desire with whatever object you decide to create, as long as it shares the same public interface.

You could create a Gun or a Sword object that uses the IWeapon interface and your Samurai class wouldn't care. Using the new keyword inside your class prevents you from being able to do that. Instead, you are forced to only use the single implementation that Samurai knows about (because it created it). So if you wanted to add another weapon later you'd have to modify the Samurai class. Implementing Samurai like that is especially gross if you're exposing it as an API to other developers because they are not going to want to muck around in your code.

So you'd do something like this:

Gun gun = new Gun();
Samurai samurai = new Samurai(gun);

The implementation would look like this:

public class Gun : IWeapon { // Implementing IWeapon, and typecasting the class into a Weapon
   public Attack(string target) {
     // Perform attack logic here
   }
}

Your interface looks like this:

public interface IWeapon {
  void Attack(string target);
}
like image 132
Walt Avatar answered Mar 28 '23 06:03

Walt