Veloxcore blog | Always Discovering |Always Sharing

Always Discovering. Always Sharing.

26 Mar 16

Dependency Injection – why we need it

Dependency injection is way to provide dependent object to a class to function properly, it is used in run time configuration changes and you can replace these dependencies with Mock/Stub objects in Unit Tests.


Dependency Injection
Dependency Injection in nutshell

One or the other time we find someone (relatively fresh in industry) trying to make you understand why he never needed dependency injection. He’d argue that he never developed a mess in code, he hardly write virtual methods or his settings are easily saved back in xml. Then why in this world he needs Dependency injection.

I’d start with saying try writing automated unit test cases and you will understand. On the other side a long answer would say, suppose you have a DBRepository class though which you interact with database (Surprise!), and you want to log some stuff from this class, hence comes the Logger class. Which means to make DBRepository class to work, it required Logger class, making Logger a dependency for DBRepository, simple. 

So whenever you need to log something you spawn a new instance of you Logger class and use it to write into log file, say:

var logger = new Logger();

This looks fine until you find that you want to implement different logger too, infect you need many loggers depending on some external condition, i.e. File system logger, database logger or TCP/IP one. And who would like to go and change each line of “new Logger()” each time you want different logger (don’t even think of practicality of it). Problem which comes with this are, no enjoyment doing it, erroneous, this is totally crazy and no body want trained monkey kind of work. So what’s the solution (obviously Dependency injection, because we are talking about it only ;-) ). So simple idea is to not depend on concrete implementation, rather user abstract representation. Hence we introduce new interface ILogger,

ILogger logger = new FileLogger();
// or
ILogger logger = new DBLogger();

Now we have simple reference to handle all types of logger, but still we need to create instance of different logger. Again patterns comes to rescue, as of now we are creating object at multiple places, why not we centralize it. A simple Factory class will give us ability to centralize logger creation logic and we get,

ILogger logger = LoggerFactory.Create();

The factory will take decision about what logger instance to create. Now you no need to worry about what object coming to you, and you can easily change the type of logger is being utilized.

Next task is to prepare factory to generate type based one something. This something can be defined in code or can come from outside configuration file (a simple XML will do). There are benefit of using configuration file, they provide you the ability to change the object creation type without compiling your application again. Think of a scenario where you have deployed your application and client comes in and say ‘Hey, I think there is a problem’ and you give them a configuration file with verbose logger type mapping for ILogger and can easily get all details that you need to understand problem client is facing, cool huh! 

We get all these benefit by just playing with the object creation location. But hey where Dependency injection, so let’s talk about it. Dependency Injection (DI) is next stop. In beginning we said that DBRepository class won’t be able to work without Logger class object so why not make it mandatory for it, that we do by adding a parameter in Constructor,

Public DBRepository(ILogger logger) { … }

This makes clear to everyone that you have to pass ILogger implementation to this class to instantiate it. Now DBRepository class always has Logger but without knowledge of who created it or who it is. And this is where a dependency injection framework comes to party, you pass your configuration file to DI framework and it will give you correct object when you need it, eliminating Factory class need. 

To conclude, Dependency injection is way to provide dependent object to a class to function properly, it is used in run time configuration changes and you can replace these dependencies with Mock/Stub objects in Unit Tests. 

PS: Here I described constructor injection technique, there is property injection also where property are initialized by DI framework with appropriate type. You can think constructor injection as mandatory while property injection as options components, and this discussion requires its own post. 

Like reading it, Share it.