Interfaces and Inversion of Control

The way I see it, there are three reasons for using an Inversion of Control (IoC) / Dependency Injection (DI) container:

  1. To decouple the actual implementation from a base class/interface (the contract), so that we can change the implementation when needed
  2. To allow the implementation itself to have services injected into it when it is built
  3. To control the lifetime of a service, for example, singleton, web request scoped, transient, etc

For #1, one common approach is to create an interface for every service that we are registering in the IoC/DI – this is actually why we call it Inversion of Control: we don’t control it, the container does. Nothing against it, but it may not be necessary: if for the service we are registering there will never, ever, be a different implementation (and we know that this may happen, like, for infrastructure code), there isn’t really a need for registering a service under an umbrella interface (or base class). Of course, this may bite us later, so we need to be really careful about it. The way I sometimes avoid interfaces is because I really don’t need them, and I end up saving some extra code and files.

The second reason is straightforward: we declare, on the implementation’s constructor, the services that we will be taking as dependencies, so that we can keep a reference to them for later usage.

Finally, reason #3, for me, its, for example, what makes Singleton an anti-pattern. Using an IoC container we can control the lifetime and have a service iinjected into our classes, transparently, without caring if there is one or more than one instances of it.

                             

3 Comments

  • IoC gets a bad rap and is controversial, for sure. I understand the apprehension, but I prefer it especially with how awesome .NET integrates it in with the hosting model these days.

    In my case, I find that I use the decorator pattern extensively if not everywhere. IoC registrations make this a snap. Nice example of this here:

    https://github.com/DragonSpark/Framework/blob/projects/Starbeam/DragonSpark.Presentation/DefaultRegistrations.cs#L18-L21

  • Another reason to use interfaces is for code clarity.
    If the service you need contains a lot of methods and your class just needs to use one of them.
    Instead of having your class depend on the entire service you make it depend on an interface that just contains that one method. You are telling future devs (or yourself in 6 months time) that all you need is that one method, not the entire service.
    That doesn't change what service is actually passed in to the class at runtime. It just provides clarity when reading the code about what the dependencies of that class actually are.

  • Jero: I agree and I am a fan of the Interface Segregation principle. What I am saying is that there is not always the need for using interfaces.

Add a Comment

As it will appear on the website

Not displayed

Your website