Dependency Injection

Sample code can be downloaded from here.

First – What is a dependency?
– We are talking about a class (say “ATest”) which needs another class (say “BTest”) to call Its (“ATest”) methods (See below example). Therefore, class “BTest” is a dependency for class “ATest”.

public class BTest
{
     public int DoBTestWork()
     {
           // Do some work
     }
}

public class ATest
{
        private readonly BTest bTest;  // Dependency
        public ATest() 
        {
            bTest = new BTest();
        }
        public void DoATestWork()
        {
            var  bTestOutput = bTest.DoBTestWork();
            // Do something with bTestOutput
        }      
}

image

 

Can we try decoupling class ATest and BTest.
Yes – try interfaces. Here in the below example. We have the same classes as above. However – this time we have the method in BTest coming from the interface IBTest. Class ATest is now have the object reference of interface IBTest instead of BTest class.

public interface IBTest
{
     int DoBTestWork()
}
public class BTest : IBTest
{
    public int DoBTestWork()
   {
   // Do some work
   }
}

public class ATest
{
    private readonly IBTest bTest;
    void ATest()
    {
      bTest = new BTest();
   }

   public void DoATestWork()
   {
      var bTestOutput = bTest.DoBTestWork();
     // Do something with bTestOutput
    } 
}

Is this good enough? No. Because we we still have the reference of BTest in the ATest class. See – the even though the object bTest is of type IBTest, It is getting instantiated from BTest. So the classes – ATest and BTest are still not decoupled.

image

What is Dependency injection?
– It’s a type of IoC which let us take out the dependencies of a class and handles their (dependencies) creation and binding. This way the class no longer has to have the references of the dependencies.

How to we implement it :-

  • Constructor Injection
  • Property/Setter Injection
  • Method Injection

Constructor Injection
Pass dependency into the dependent class via the constructor. Here, the constructor on ATest is taking an interface of IBTest and we don’t have any reference of the concrete class BTest.

public interface IBTest
{
        int DoBTestWork()
}

public class BTest : IBTest
{
          public int DoBTestWork()
          {
             // Do some work
          }
}

public class ATest
{
         private readonly IBTest bTest;
         void ATest (IBTest bTest)
         {
           this.bTest = bTest;
          }

          public void DoATestWork()
          {
            var bTestOutput = bTest.DoBTestWork();
            // Do something with bTestOutput
          } 
}

Following is the code which would call use ATest and pass the its dependency BTest in it.

IBTest bTest = new BTest();
ATest aTest = new ATest(bTest);
aTest.DoATestWork();

Property/Setter Injection
Don’t pass dependency in the constructor of the dependent class. Just have the interface dependency types as public properties in the dependent class.

public interface IBTest
{
       int DoBTestWork()
}

public class BTest : IBTest
{
       public int DoBTestWork()
      {
       // Do some work
      }
}

public class ATest
{
       public IBTest BTestObject { get; set; }
       public void DoATestWork()
       {
         var bTestOutput = BTestObject.DoBTestWork();
        // Do something with bTestOutput
        } 
}

Following is the code which would call use ATest. It just sets the the public property of dependency interface type (IBTest) to the concrete type(BTest).

IBTest bTest = new BTest();
ATest aTest = new ATest();
aTest.BTestObject = bTest;
aTest.DoATestWork();

We should use this have some optional properties and having those properties not assigned won’t impact calling methods.

Method Injection
Don’t pass dependencies in the constructor or set them on the properties of the dependent class. Just pass them in the method of the dependent class.

public interface IBTest
{
   int DoBTestWork()
}

public class BTest : IBTest
{
     public int DoBTestWork()
     {
        // Do some work
     }
}

public class ATest
{
       public void DoATestWork(IBTest bTest)
       {
          var bTestOutput = bTest.DoBTestWork();
         // Do something with bTestOutput
       } 
}

Following is the code which would call use ATest. It just passes the dependency interface type (IBTest) to the dependent ATest method DoATestWork.

ATest aTest = new aTest();
IBTest bTest = new BTest();
aTest.DoATestWork(bTest);

, ,

  1. Inversion of Control (IoC) « Fix the broken window
  2. Unit testing a static method which calls another static method « Fix the broken window

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 )

Facebook photo

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

Connecting to %s

Random Thoughts

The World as I see it

Simple Programmer

Making The Complex Simple

Ionic Solutions

Random thoughts on software construction, design patterns and optimization.

Long (Way) Off

A tragic's view from the cricket hinterlands

%d bloggers like this: