3

I heard one of the developers at work mention that the whole point of DI is supposed to be the use of interfaces. The usage of concrete classes should be kept to a minimum as a thumb rule. 
If there are more than a handful instances where we configure DI to use specific classes, then its a code smell.

Now I'm not sure If I can take this as a point blank rule. The one big reason for DI, that I always felt was the ease of Testing.

There may be other reasons to use an interface, over concrete classes as dependency in my code(say ease of plugging in other implementation of a logic, etc.), but I can't see how the use of Dependency Injection implies that.

EDIT: Assume I have a class BookingMapper which maps Booking objects from one domain to another. Let's say it has a Hotel object which it needs to map as a part of mapping the Booking. It uses HotelMapper class to do the same.

public class Booking
{
    ...
    Hotel Hotel;
}

public class BookingMapper
{
    private readonly HotelMapper hotelMapper;
    public BookingMapper(HotelMapper hotelMapper)
     {
      this.hotelMapper = hotelMapper;
     }
    Map(){...}
}
public class HotelMapper
{
     Map(){...}
}

In such use cases, I already know that at all points my Booking Mapper component will be at the same level as my HotelMapper, and it is separated out due to Single Responsibilty Principleenter link description here. Does it still make sense for me to extract out an interface like

public interface IHotelMapper
{
void Map();
}
public class BookingMapper
    {
        private readonly IHotelMapper hotelMapper;
        public BookingMapper(IHotelMapper hotelMapper)
         {
          this.hotelMapper = hotelMapper;
         }
        Map(){...}
    }

and then use that as the dependency in BookingMapper than using HotelMapper directly ?

noob Mama
  • 267
  • 8
  • 28
  • possible duplicate of [Dependency injection with interfaces or classes](http://stackoverflow.com/questions/10311571/dependency-injection-with-interfaces-or-classes) – Travis J Jun 25 '13 at 18:23
  • There we mostly address why creating a 1-1 relationship between an interface and a concrete class is a problem(as in breaking change in interfaces). While, here I'm rather trying to understand why is it(if any) a hard and fast rule to always create these 1-1 relationships, when can i skip doing that. – noob Mama Jun 25 '13 at 19:00
  • There are already some good answers to that on this site. [Dependency injection with interfaces or classes](http://stackoverflow.com/questions/10311571/dependency-injection-with-interfaces-or-classes?rq=1) explains rather well why interfaces, while strictly speaking are not a requirement, do make a lot of sense. – mario Jun 25 '13 at 18:15
  • Thanks for the link, but we're mostly discussing, the problems with using an interface over an instance in that post. What I'm interested to know is what exactly is the incentive in using the interface itself. The closest answer to that i can get off that page is this "I would stick with interfaces. They are designed to be contracts for consumption for external entities." While I agree with the general idea in using interfaces, I'm not sure if i can apply this to every scenario where I'm using a DI. – noob Mama Jun 25 '13 at 19:11

2 Answers2

1

Take a look at the SOLIDprinciples, then look at them again. You'll see that DI and interface-based designs are big parts of OOP. It think you'll agree that your co-worker is making a lot of sense. And yes, you are right that DI will make you're testing easier/better.

http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)

Big Daddy
  • 5,160
  • 5
  • 46
  • 76
  • Thanks, that was a good read. To be precise the principle that applies here is the Dependency Inversion Principle. But then again.. the use case talks of Higher Level Components relying on Lower Level components. Buy If i consider the case where I have a dependency on a same level component,(say a Mapper class or a Factory for instance), I still feel such cases can be an exception to this rule ? don't u think – noob Mama Jun 25 '13 at 18:49
  • @noobMama... Can there be exceptions? Yes, that's why DI containers such as Unity provide functionality for instances. Personally, I almost exclusively use interfaces for DI, but have used instances, too. – Big Daddy Jun 25 '13 at 18:56
  • Hmm.., so in conclusion I'd take use of an interface over an instance more as a guideline, rather than a hard and fast rule. – noob Mama Jun 25 '13 at 19:05
  • You should think interface first. This should be your rule. Deviate for edge cases only. Your code will be better. – Big Daddy Jun 25 '13 at 19:11
1

Dependency Injection is a pattern that by itself can be used completely without defining interfaces. You can let consumers depend on other concrete classes. By making important methods of these classes virtual, you can even derive fake implementations out of them for testing purposes.

There are however a many advantages when depending on abstractions instead of implementations:

  • Testing becomes much easier and safer, because you're not dragging the real implementations behind.
  • Parts of your application can be deployed seperately, because consumers only depend on an abstraction, not the implementation.
  • Appending behavior by using the decorator pattern (or using other AOP techniques such as interception) are much easier when dealing with interfaces.
Steven
  • 166,672
  • 24
  • 332
  • 435