Dependency Injection

18 Jan 2011. comments

What is dependency injection? Lets look at some code.

public class Foo  
{  
  private Bar bar;  

  public Foo()  
  {  
    bar = new Bar("Alpha", 123);  
  }  

  public void Baz()  
  {  
    bar.Fire();  
  }  
}

The above example is an example of tightly coupled classes. Foo is completely dependant on the concrete Bar. This isn’t ideal because a change to Bar will cascade into Foo. We also can’t change the implementation to some other kind of dependency with the same interface; we have to use this concrete Bar.

How can we improve this?

public class Foo  
{  
  private Bar bar;  

  public Foo(string name, int number)  
  {  
    bar = new Bar(name, number);  
  }  

  public void Baz()  
  {  
    bar.Fire();  
  }  
}

This is slightly better because we can specify parameters for a little more flexibility but it still doesn’t solve the original problem of depending on Bar’s concrete implementation.

public class Foo  
{  
  private Bar bar;  

  public Foo(Bar bar)  
  {  
    this.bar = bar;  
  }  

  public void Baz()  
  {  
    bar.Fire();  
  }  
}

With this change we can now pass in a Bar or any subclass of Bar. This is dependency injection in its simplest form. This is an improvement since we now have the flexibility beyond just using a Bar we made but still not great because it forces the dependency to inherit from a concrete implementation.

public class Foo  
{  
  private IBar bar;  

  public Foo(IBar bar)  
  {  
    this.bar = bar;  
  }  

  public void Baz()  
  {  
    bar.Fire();  
  }  
}

This is better because now we’re depending on an interface IBar that’s passed in and responds to methods we want to use. We don’t necessarily care what the actual concrete is so long as it has a Fire() method. And since it’s an interface we don’t force our dependency to inherit from a concrete.

These examples highlight the concepts of dependency-injection and inversion-of-control at their simplest form; pass in dependencies as non-concretes which keeps code decoupled and allows the object being injected into to use a dependency without knowing its actual type.

comments

Tagged: dependency injection inversion of control design patterns C#

2017 Ben Lakey

The words here do not reflect those of my employer.