Real world example of Dependeny Injection

Synopsis: Real world example in which Dependency Injection is used to be able to replace a class without recompiling. Github: https://github.com/DannyvanderKraan/LogInService.git

Intro

I was  trying to wrap my head around Dependency Injection, one of the many practices which helps you apply the conceptual design pattern Inversion of Control. And I couldn’t find a lot of real world examples, which were simple enough to explain in a short blogpost. There were some, but it’s just a complex subject, which doesn’t lend itself well to this medium. But if you learn like me (colorful pictures and easy words) a real world example which is simple to understand can help a great deal. So that is goal of this blogpost. I came across a  really nice case study for Dependency Injection (DI) while helping a colleague of mine, which helped  me understand DI a bit more. And hopefully I can help other developers wrap their heads around it as well. Now before we dive in you should know that almost everything I know about it (if not all) is from Mark Seemann‘s book “Dependency Injection in .NET”. So if you want to know more about DI I highly recommend this book. Ok, here we go!

Case

Our users need to log in with a smartcard to gain acces to the informationsystem. So we just grabbed one of the more popular cardreaders. And found ourselves a  nice little 3rd party library to help us detect if the smartcard is in or out the reader, because the system needs to respond to this change. We built a wrapper around this 3rd party library (Facade pattern basically). This looked like the following model:

2015-06-13 11_17_12-Document1 - Microsoft Word
Figure 1

  • LogInService; the class that needs to know if the card is in or out and deal with that accordingly, but doesn’t want to know about the 3rd Party Library’s API (because it might change in the future and arguments like that).
    In the constructor it initializes an instance of CardPresenceChecker and sets MyCardPresenceChecker with this instance. It adds handlers to the events CardIn and CardOut. It calls the void method Init() on MyCardPresenceChecker to initialize the checking of the cardreader. 
  • CardPresenceChecker; the only class which knows the foreign API intimately by wrapping the 3rd Party Library’s API in a simple and clean API of our own.
    Interface looks like:
    – void Init() (makes the 3rd party library start checking the cardreader)
    – event EventHandler CardIn (handle this event if you need to know if the card is in)
    – event EventHandler CardOut (handle this event if you need to know the card is out)
  • 3rd Party Library; The actual 3rd party library that does all the real work for us.

Problem

This is pretty tightly coupled. We discovered in the documentation of the 3rd party library that for the number of devices supported there could potentially be an equally long list of devices not supported. A wrapper class is only going to help if in the future we switch from 3rd party library for all customers. Not if some customers need 3rd party library X and some customers need 3rd party library Y because they bought some other cardreader. So I was reading this book by some Mark Seemann about this odd little thing called Dependency Injection and so I said to my colleague: Eureka! I think I can relieve our stress a bit by refactoring our code and utilize the power of DI. Observe the following changes to the original design:

2015-06-13 12_29_47-Document1 - Microsoft Word
Figure 2

We went for the “Constructor Injection” pattern to implement DI and the refactoring steps were:

  1. Abstract the interface of CardPresenceChecker by creating Interface ICardPresenceChecker;
  2. Make explicit that this CardPresenceChecker only works for the library of Company X, by changing its name to XCardPresenceChecker ;
  3. Have XCardPresenceChecker implement Interface ICardPresenceChecker ;
  4. Abstract the property of LogInService to be of type ICardPresenceChecker instead of ‘knowing’ exactly which implementation is held aboard;
  5. And last but not least, demand from users (other developers) of LogInService that they provide any class that at least implements ICardPresenceChecker so that LogInService can do its thing.

LogInService’s constructor looks like:

this.myCardPresenceChecker = cardPresenceChecker;
this.myCardPresenceChecker.CardIn += MyCardPresenceChecker_CardIn;
this.myCardPresenceChecker.CardOut += MyCardPresenceChecker_CardOut;
this.myCardPresenceChecker.Init();

So where do you provide LogInService with an implementation of ICardPresenceChecker? You usually want this ‘mapping’ (in this example we would ‘map’ ICardPresenceChecker to XCardPresenceChecker) at one central place at the startup of an  application, known conceptually as the “Composition Root”. For an ol’ regular Console Application that could be the void Main in the Program class. So for this example, this piece of code would be used at the aformentioned place:

LogInService logInService = new LogInService(new XCardPresenceChecker());

Problem 2

Although I have taken a real example from my work it is obviously still extremely simplified. Because for instance our LogInService needs another 3rd party library to handle the actual authentication of the smartcard. So imagine expanding the model at figure 2 like this:

2015-06-13 19_46_24-Document1 - Microsoft Word
Figure 3

Our little model has become more complex with an extra dependency for the LogInService, wouldn’t you agree? Imagine that ACardAuthenticator demands a dependency also to, for instance, log any failed authentication. Imagine XCardPresenceChecker has a seperate dependency to be able to tell through some other 3rd party library if the physical  card reader is still connected to the computer or not. Well you can imagine how this can become pretty complex really fast. Imagine typing:

LogInService logInService = new LogInService(new XCardPresenceChecker(new SomeCardReaderPresenceChecker()), new ACardAuthenticator(new SomeLogger()));

But all I want to type is this really:

LogInService logInService = container.Resolve();

The solution to this problem are IoC (Inversion of Control)  Containers, like Unity (used in example above), Castle Windsor and StructureMap for instance. We’ve used what is called “Poor man’s” Dependency Injection through the Constructor Injection pattern up ’til now. And there is nothing wrong with that, you could write your entire application like this. But to avoid getting my co-workers really confused and annoyed with me pushing DI  I took Unity by Microsoft for a spin (this is not a blogpost about what IoC Container you should use or even if you should use one at all).

Via NuGet you can get the latest Unity 3.0 in your solution. It should add the dlls: Microsoft.Practices.Unity, Microsoft.Practices.Unity.Configuration and Microsoft.Practices.Unity.RegistrationByConvention to your solution. If the solution is still a Console Application and we are still using void Main of class Program as our Composition Root then add this to the top of the file:

using Microsoft.Practices.Unity;

And add this piece of code to void Main:

IUnityContainer container = new UnityContainer();
container.RegisterType();
LogInService logInService = container.Resolve();

I am following the model in figure 2, just to get back to our simplified example again. But from this code sample you should be able to easily derive how you can use RegisterType to map every Interface to the Class you want to use. The ‘magic’ happens at Resolve, where we just throw in LogInService and Unity uses the constructors to see which dependencies are needed and uses the registrations (mappings) to initialize the right objects and pass them in the constructors. I thought this was pretty cool and wanted to share this with you. But then I thought of the next situation…

Problem 3

The reality will be that some customers use card reader Foo so we need the 3rd party library of company X and some will use  card reader Bar so we need the library of company Y. We don’t want to make a LogInServiceX.dll and a LogInServiceY.dll obviously, we want to use one LogInService.dll and we even want to switch CardPresenceChecker classes without recompiling! Say hello to ‘late binding’ via Dependency Injection through XML configuration files and Unity’s ability to resolve these easily (again an IoC Container is not required but makes the code a lot more readable). Quick word about late binding though, because it uses the configuration file, please do so with care. The configuration file is prone to errors. Always register your mappings in code so you get compile time checking, unless you really have no other option. Please observe the following changes I made to the model:

2015-06-13 21_51_26-Document1 - Microsoft Word

I have put Interface ICardPresenceChecker and the class XCardPresenceChecker each in their own assembly. Note that the LogInService.dll references the LogInService.Interfaces.dll and that the XCardPresenceChecker.dll references the LogInService.Interfaces.dll too. Please note that there is no reference between LogInService.dll and XCardPresenceChecker.dll! In the App.config we put the following xml:

2015-06-15 07_52_35-LogInService - Microsoft Visual Studio

Please observe that Section “unity” was added to the configSections and that in Configuration there is a Unity tag. The unity tag can contain Containers. There’s one Container added. A Container can have Types registered (remember the RegisterType method?). There’s one Type registered which maps ICardPresenceChecker to XCardPresenceChecker (across assemblies as you must note).

Changes are made to void Main too:

IUnityContainer container = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(container);
LogInService logInService = container.Resolve();

The “unity” section is retrieved from the config file and used by calling .Configure to configure the Container. In this case it will map ICardPresenceChecker to XCardPresenceChecker. And the .Resolve call on the Container will again magically instantiate LogInService by injecting an instance of XCardPresenceChecker in the constructor (don’t forget to put theXCardPresenceChecker.dll in the same folder as the LogInService.exe if you are building along). How awesome is that?!

Testing

Now start a new Class Library called YCardPresenceChecker with an YCardPresenceChecker class in it. Reference LogInService.Interfaces.dll and have YCardPresenceChecker  implement interface ICardPresenceChecker. Build the solution and copy the  baked dll to wherever your LogInService.exe is (in the example project on my Github LogInService is a Console application). Do not recompile LogInService.exe! All you do is switch out every instance of XCardPresenceChecker for YCardPresenceChecker in the file: LogInService.exe.config.  Now when you fire up LogInService the call to .Resolve will instantiate LogInService by injecting an instance of YCardPresenceChecker in the constructor! Again, how awesome is that?!

By the way, if you are building a long, I simply checked if this worked by handling the CardIn and CardOut events with the following code (change ‘out’ to ‘in’ accordingly):

Console.WriteLine(string.Format("{0} said the card is out!", sender));

ToString is called on sender, which just prints the name of the class on the Console so I can see what class is being used right now.

Note: The observant reader understands by now the major gift that DI gives you. Imagine adding a MockCardPresenceChecker instead of an YCardPresenceChecker, so you can build really nice Unit Tests on the ‘unit of work’ identified as LogInService. This will be the focus in another blogpost, so stay tuned.

Outro

I showed a real life example of DI from me at work to explain the basic concepts, which just happened to concern ‘late binding’. DI is also (if not mainly) about maintainability, flexibility, extensibility and also unit testing. I’ll elaborate on these aspects in blogposts yet to come. Thank you very much for reading this and as usual if you have any questions, feedback or whatever leave a comment!

You can get the example from my Github: https://github.com/DannyvanderKraan/LogInService.git (LogInService.dll = LogInService.exe). Make a ZCardPresenceChecker for fun!

* Thanks Roy Cornelissen for your excellent feedback on this post.

*2 Sometimes certain characters disappear from the code blocks. The code is on my github, so please check there, while I sort this out.

Advertisements

About Danny

Bachelor in Commercial ICT MCTS Winforms .NET 2.0 MCTS ASP.NET 3.5 PSM I
This entry was posted in .NET programming, C#, Dependency Injection, Software design patterns and tagged , , , , . Bookmark the permalink.

2 Responses to Real world example of Dependeny Injection

  1. Pingback: Real World Example of Adding Auditing With Dependency Injection’s Interception | Danny van der Kraan's Blog

  2. Pingback: Unit Testing made easy with Dependency Injection | Danny van der Kraan's Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s