Constructor Dependency Injection in C# .Net

Dependency Injection in C# .Net can be confusing to those who are new to the paradigm. But that doesn't have to be the case, especially if constructor injection is being used.

To illustrate, let's build a small object in code with supporting classes, and verify that it works. Then afterwards we can rebuild the same project using constructor Dependency Injection, and I think you will see exactly how simple and convenient it can be for any number of purposes.

Non-Injected Version

Okay, let's build our objects. Since this is NerdBeach, we will opt to nerd out and build a bold and daring Starfleet Officer, complete with phaser. First up, the phaser:

class Phaser
{
    public void Fire(string setting)
    {
        Console.WriteLine("Phaser fired with setting {0}", setting);
    }
}

Okay, we have our phaser object, and we can fire the weapon at a setting of our choice (stun, kill, and disintegrate, naturally). Now we just need a brave Starfleet Officer to use it.

class Officer
{
    readonly Phaser phaser;
    public Officer()
    {
        this.phaser = new Phaser();
    }

    public void Attack(string setting)
    {
        this.phaser.Fire(setting);
    }
}

Now we just need to pull it all together and set our Starfleet Officer in action:

class Program
{
    public static void Main()
    {
        var RickyRedShirt = new Officer;
        RickyRedShirt.Attack("Stun");
    }
}

When we run this, we get the following output:

Phaser fired with setting Stun.

This is good, but perhaps we want RickyRedShirt to live up to his name and pack only a tricorder. As it is, the phaser is built inside of the Officer's class constructor. To change change it, we are going to have to modify the class implementation. This is an example of a concrete dependency, and right now the Officer is tightly coupled to the aforementioned phaser.

Instead, let's break that concrete dependency and use an interface to specify Ricky's equipment. First, we can create an equipment interface (with a more general purpose "Activate" intend of "Fire").

interface IEquipment
{
    void Activate(string setting);
}

Now we implement the interface with our equipment – namely a phaser for now.

class Phaser : IEquipment
{
    public void Activate(string setting)
    {
        Console.WriteLine("Phaser fired with setting {0}.", setting);
    }
}

class Officer
{
    readonly IEquipment equipment;
    public Officer()
    {
        this.equipment = new Phaser();
    }

    public void UseEquipment(string setting)
    {
        this.phaser.Activate(setting);
    }
}

Cool, we have the ability to create new iEquipment equipment as required, and our Starfleet officer can take advantage. But we still have one issue – the phaser is STILL tightly coupled to our officer. But there is an easy solution to this.

 

Injected Version

Complete project file: ConstructorDependencyInjection.zip (35.90 kb)

Instead of specifying what kind of equipment our officer is carrying within the Officer constructor, we can pass it to the contractor as a parameter instead. Consider the following:

class Officer
{
    readonly IEquipment equipment;
    public Officer(IEquipment Equipment)
    {
        this.equipment = Equipment;
    }

    public void UseEquipment(string setting)
    {
        this.equipment.Activate(setting);
    }
}

Now we can equip our officer as needed right from the constructor. In fact, this is a great example of Constructor Dependency Injection. Let's create an IEquipment version of tricorder for our officers.

class Tricorder : IEquipment
{
    public void Activate(string setting)
    {
        Console.WriteLine("Tricoder scanned for {0}, found plenty.", setting);
    }
}

Now we can create our landing party, and assign equipment to our officers as we see fit.

class Program
{
    public static void Main()
    {
        var Spock = new Officer(new Phaser());
        var Kirk = new Officer(new Phaser());
        var RickyRedShirt = new Officer(new Tricorder());

        Spock.UseEquipment("Stun");
        Kirk.UseEquipment("Stun");
        RickyRedShirt.UseEquipment("Life Signs");
    }
}

When we run this, our landing party is created and snaps into action. The action unfolds as follows:

Phaser fired at setting Stun
Phaser fired at setting Stun
Tricoder scanned for Life Signs, found plenty.

So there you have it. In our landing party, Kirk and Spock fired their dependency injected phasers and blocked a vicious attack. Unfortunately RickRedShirt, armed only with a tricorder, detected life signs only moments before he was attacked. Too bad for Ensign Ricky.

This example shows how easy it is to set up Dependency Injection using a constructor. We can create virtually any type of IEquipment device to equip our officers with at runtime, all without modification of the Officer class itself. In practical use we may be using mock classes or plugins in a test environment, but the concept is the same.

This approach is also known as manual injection (or Dependency Injection by Hand), since it requires the creation of an IEquipment class for each test scenario. While this works great for small projects, a more complex need (logging, dependencies, etc.) can quickly become a pain to maintain. For those needs, it might be best to look at an IoC (Inversion of Control) framework to help you manage it all. But that is a conversation for another time.

 

Dependency Injection

Dependency injection is a software design pattern that allows a choice of component to be made at run-time rather than compile time. This can be used, for example, as a simple way to load plugins dynamically or to choose mock objects in test environments vs. real objects in production environments.

source:wikipedia 

 

ConstructorDependencyInjection.zip (35.90 kb)

Share and Enjoy
  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
Pinterest
Email
Print
WP Socializer Aakash Web