4

I create a class that applies to dependency inversion principle, and used the dependency injection pattern, as follows:

public interface ITypeOfPrinter
{
    string Printing();
}

public class Print
{  
    private readonly ITypeOfPrinter _typeOfPrinter;

    public Print(ITypeOfPrinter typeOfPrinter)
    {
        _typeOfPrinter = typeOfPrinter;
    }

    public string print()
    {
        return _typeOfPrinter.Printing();
    }
}

public class BlackAndWhitePrinter : ITypeOfPrinter
{
    public string Printing()
    {
        NumberOfPrints++;
        return string.Format("it is Black and white printing {0}", NumberOfPrints);
    }

    public int NumberOfPrints { get; set; }

}
public class ColorfullPrinter : ITypeOfPrinter
{
    public string Printing()
    {
        NumberOfPrints++;
        return string.Format("it is colorfull printing {0}", NumberOfPrints);
    }
    public int NumberOfPrints { get; set; }
}

So if I want to use BlackAndWhitePrinter, I simply create an instance object and give it to my Print class with construction as follows:

ITypeOfPrinter typeofprinter = new BlackAndWhitePrinter();
Print hp = new Print(typeofprinter);
hp.print();

So Why I have to use Unity or another IoC framework here? I already did what I want as above:

var unityContainer = new UnityContainer();
unityContainer.RegisterType<ITypeOfPrinter, BlackAndWhitePrinter>();
var print = unityContainer.Resolve<Print>();
string colorfullText = print.print();
Steven
  • 166,672
  • 24
  • 332
  • 435
Michael Riva
  • 531
  • 1
  • 7
  • 16
  • 4
    You *don't* have to use an IoC container to conform to the dependency inversion principle. See http://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer/. – Preston Guillot May 22 '14 at 20:33

2 Answers2

7

Dependency Injection as a pattern helps making your application code more maintainable. DI frameworks (a.k.a. IoC containers) can help making the Composition Root more maintainable.

But, if a IoC container doesn't help making your Composition Root more maintainable, don't use it in that scenario! That doesn't mean however that you shouldn't use Dependency Injection or other patterns and principles that help making your software more maintainable. You should whatever it takes to lower the total cost of ownership of the software you are building.

Steven
  • 166,672
  • 24
  • 332
  • 435
6

Just as an addendum to Steven's answer, there are a couple of compelling reasons for using an IOC framework which don't apply in the simple example you gave but can easily apply for more complex apps; but I agree that you don't actually have to use one if you don't feel it brings benefits.

When your classes are not directly created by you, but rather by a framework.

Typical example of this is an ASP.NET Controller / ApiController. You never instantiate these yourself, the ASP.NET framework does this for you. In this case if your controllers have dependencies then an IOC framework allows you to easily declare these dependencies by interface on the controllers and not worry about how they get supplied.

This decouples your classes, as well as allowing easier unit testing because you can mock/stub the dependencies.

When you have complex object graphs that have to be constructed. Below is an anonymisd but otherwise real graph from a project I am working on:

 new DeathStar(new NotAMoon(),
               new PlanetExploder(),
                new ExhaustPort(new CriticalVulnerabilityIgnorer()),
                new StormTrooperGenerator(new DodgyBlasterGenerator(),
                    new HeadDoorBumper(new Ouch()),
                    new ShieldGenerator(new FurryCreatureVulnerability)),
                    new DramaticDuel(new Saber()), new DeadJedi()),
                new DroidFactory(),
                new TrashCompactor(new Monster()),
                new Emperor(new Vader())
            );

Don't know about you, but I wouldn't fancy having to type this (let alone try to maintain or debug it) when I needed a new IDeathStar - I'd much rather say

var moon= IOCFrameworkOfChoice.Resolve<IDeathStar>();

or more realistically:

public class MyController: Controller
{
    public MyController(IDeathStar star)
    {
        //at runtime, at this point I have an armed and fully operational IDeathStar
        //without having to worry about where it came from!
    }
}
Community
  • 1
  • 1
Stephen Byrne
  • 7,400
  • 1
  • 31
  • 51