BLOG

Dependency Injection

Tue, 02/15/2011 - 10:42

A few weeks ago, we started thinking about a new product, as every new project, at the beginning it’s exciting, everything is new and so forth, nothing can go wrong! Every decision affects the future of the product so, if we don’t take the necessary amount of time to properly design the application, we can produce a brand new future nightmare!

There are two main goals we must achieve to success on this new project; it should be extensible and maintainable, but how can we accomplish both? Well, thankfully it is not impossible. In this blog post we are going to talk about how can we make this new app maintainable, or at least, how can we start thinking about it Wink.

One way to help this principle is decoupling our classes, class coupling increases code complexity as we have classes depending on each other, at early stages this is not a big deal, but once we have a really large and complex product then class coupling can become our worst enemy! Image you have a very large project with many components and all them have knowledge of all other components, for example, this imaginary project has a logging, database, file handling, UI and session handling components, and every component are connected with each other, now let’s pretend to change the session handling component for a better one, it will be a real nightmare! We might need to change everything as every component has a direct relation with this session component.

Class decoupling avoids this kind of problems as we won’t have any connection between components, so changing one of them would be just keeping an interface or contract limiting changes to only the component that implements that interface, there is no need to change the rest of the application.

Looks pretty straightforward, but, how can get components using other components without even knowing them? I mean… someone has to connect components with each other! Here is where Dependency Injections becomes the star of the show.

According to Wikipedia, DI is “a technique that indicates to a part of a program which other parts it can use”, basically,is to give all the knowledge in relations between objects to an expert, who then become responsible for instantiating the correct objects with their dependencies, we can achieve this ourselves, but, why reinventing the wheel? There are several great DI containers that can handle this task, after reviewing a few of those; my winner is Unity (http://unity.codeplex.com/).

Here is a very small example of how Unity can help with maintainability issues:

The next image shows a very simple class diagram, usually, Interfaces are not used when there are no plans of using any IoC or DI, so my first version of this diagram had no interfaces, let’s pretend the relations are directly with the objects and not Interfaces.

Now, how should I create a new instance of a MySqlProvider class? Pretty easy… I should do as the following image.

See there is a line “m= new DataProviders.MySqlProvider” blah blah blah?? Well it is pretty easy, but… what if I change the AppSettingsConfigurationManager for a different object? Let’s say… configuration based on DB? Well, we create a new class and then we change MySqlProvider to receive an instance of this new object instead of appSettingsConfigurationManager, ok wait… that’s can’t be right...

With DI, we make relations and dependencies against Interfaces, it is a formal contract so the dependant object knows which operation to ask, but doesn’t care who is going to perform that operation, so this is when the class diagram gets a little more logical, now, what we need now is to let the DI container do his job… and release us from the heavy duty of creating all instance of our dependencies all the time.

Here is an image of a Mapping configuration for Unity:

As you can see, there are three interfaces, and then three implementations, after that, we have all our mappings and dependencies, this means that any time we ask for an object of IConfigurationManager, Unity will return a AppSettingsConfigurationManager object, and if we ask for a IWorkflowCaseProvider we will get a MySqlProvider instance with an instance of AppSettingsConfigurationManager already injected in it!

 

So, how should our code look like? Here is it:

This is far more maintainable than the last code, for example, if we change our way of saving workflows (to Sql Server instead of MySql for instance) then that change is completely Transparent to our main code, it is just a configuration setting. Also if we realize that we need three more dependencies inside a MySqlProvider, just changing our Unity configuration is enough, no code changes to the rest of the components Laughing

Hope you like it!!

.Net Developer
Senior developer interested in multitier architecture, web based, back-end and core app design and development.