The Stack Overflow Inspired Knowledge Exchange Series
TOC Checkout the project homepage of this series to follow our journey from the creation of the famous StackOverFlow website.
Introduction
In the last article we walked through a discussion of how code that does not follow the dependency injection pattern is not as testable as code that does. With an understanding of how dependency injection works and why it is important we were then able to walk through the majority of our code to refactor towards the dependency injection pattern. Once our code was refactored to implement dependency injection we were then able to write some tests around our code. We did find that towards the end of the article there were parts of our code that we did not have total control over and therefore were unable to convert it to a testable format. With these issues identified we were able to discuss some approaches to fix them which were to be discussed in this article.
In this article we will discuss how we can enhance the power of the Dependency Injection pattern by implementing an Inversion of Control container. We will discuss what an IoC container can be used for and how it works. Then we will look at implementing an Inversion of Control container in our code. We will specifically implement the IoC container StructureMap. Once StructureMap is plugged in and working we will once again refactor our code to take advantage of the new features and functionalities that StructureMap provides us with. And with that refactoring completed we can then address the Controller issue that we found in the last article by creating a custom ControllerFactory that will take care of locating and returning a custom controller and will also take you care of instantiating our dependencies in an automated fashion using StructureMap. With all of our wrinkles ironed out we will then be able to test our HomeController.
Introducing Inversion of Control
Dependency Inversion is a specific form of Inversion of Control. Having implemented Dependency Injection in our code we are just a few quick steps away from implementing an Inversion of Control (IoC) container in our code. There are many IoC's out there and all work in a similar fashion. The basic idea of using an IoC container is that rather saying Widget widget1 = new Widget; and having that hard coded dependency right there in your code you could instead say IWidget widget1 = Container.GoGetMeAWidgetThatImplementsThisInterface<IWidget>();. The power here is that your code won't have a direct dependency on any other code. The IoC will automagically take care of dependencies by way of configuration (in all sorts of fashions). What is nice about this for what we are doing is that we can configure which dependencies are used in production and which dependencies are used while in testing.
An IoC container can be used for even more than just testing productivity. You can also use an IoC container as a mechanism for a plugin architecture, a way to provide conveniences to your development environment, or to provide a path to scalability by way of allowing you to plug in more scalable components as you need them.
Introducing an Inversion of Control (IoC) container - StructureMap
StructureMap is the IoC container that I have been using for the past several years. I have yet to find an instance that StructureMap didn't do what I needed it to do at that time so I have not tried any of the many other IoC containers that exist out there. I don't feel that this article would really be complete though without mentioning at least some of the top alternatives that exist out there.
Table 1: Inversion of Control Containers
Name | Description |
StructureMap |
Castle | [enterprise framework] Castle is an open source project for .net that aspires to simplify the development of enterprise and web applications. Offering a set of tools (working together or independently) and integration with others open source projects, Castle helps you get more done with less code and in less time. |
Spring.NET | [enterprise framework] Spring.NET provides comprehensive infrastructural support for developing enterprise .NET applications. It allows you to remove incidental complexity when using the base class libraries makes best practices, such as test driven development, easy practices. Spring.NET is created, supported and sustained by SpringSource. | The design of Spring.NET is based on the Java version of the Spring Framework, which has shown real-world benefits and is used in thousands of enterprise applications world wide. Spring .NET is not a quick port from the Java version, but rather a 'spiritual port' based on following proven architectural and design patterns in that are not tied to a particular platform. |
ObjectBuilder | ObjectBuilder is a framework for building dependency injection systems, originally written by the Microsoft patterns and practices group. |
Autofac |
What I like StructureMap for is that it does just one thing really well - inversion of control. Unlike many of the alternatives that provide all sorts of enterprise type framework oriented features StructureMap sticks to doing its job well.
Another thing that I like StructureMap for is the ease of configuration that that framework provides. I can configure StructureMap with a configuration file and attributes, or I can configure it with a registry, or I can configure it inline programitcally.
By configuration and attributes
In this format there are three steps to wiring up StructureMap. First you configure each assembly that you want StructureMap to be in charge of by specifying the assemblies for it to reflect over. By default you don't have to specify all of the PluginFamily nodes but it is easier to see what is going on for swapping types out later. You specify a PluginFamily with a PluginFamily section for each type in the config file by specifying the Assembly that has the type, the type in that assembly that you are configuring, and the key for the instance of that type that you want mapped in.
Listing 1: StructureMap.config
Second you need to tag each of the interfaces that StructureMap is to be in charge of by specifying a PluginFamily attribute and the name of the default type that will be mapped in if no other specification is provided. Where you see ("Default") in the code below you can actually specify any name you wish as long as it corresponds to a type (which we handle in the third step).
Listing 2: IPostService.cs
Third and finally we add a Pluggable attribute to each of the types that inherit from the interface that was mapped into StructureMap in the second step. Here you will see the reuse of the word Default. Again this name can be anything.
Listing 3: PostService.cs
More on the key nameI figured it was worth mentioning a bit more about the key name as I find it confuses people a bit their first time out. Where you see Default mentioned in the interface attribute and a corresponding Default key name on the actual implementation these are simply used for mapping for StructureMap. To give a more concrete example of how this works think about a caching system. We might have a local developer cache that works to speed up a developers machine while they are working (say using Lucene to create a disk cache) which we can call LocalCache. Then we could have another cache implementation that works really well on a single server installation say in a QA type environment which we could call SingleServerCache. And finally we could have a cache implementation that works in a webfarm environment using MemCached or similar which we might call WebFarmCache. Each of these cache names, LocalCache, SingleServerCache, and WebFarmCache is what would be specified above the actual class where we specify the Pluggable(“”) attribute. Then when we configure the default instance for an interface that each of these cache implementations inherits from we could choose to specify PluginFamily("LocalCache") as the default key to use. Later we could override our default implementation by specifying one of the other two keys (we will see how this works later).
Using a registry to wire up StructureMap
The idea of a registry is that I can have a class that configures all of the moving pieces in a project that can then be wired up externally depending on the environment that I am in. This method is nice in that it doesn't litter StructureMap code all over my codebase which means that I could later fall in love with the Sping.NET framework and wire it in if I so chose. By this I mean to say that I won't need the StructureMap.config or any interface or class based attributes to take care of my configuration needs. What this also means is that my configuration is hard coded and can't simply be rewired on the fly. Choose what works best for your application and environment.
In order to use this method to wire up StructureMap you need to do three things (three totally different things). The first is to create a registry class (call it what you will) that inherits from StructureMap.Configuration.DSL.Registry. The second thing is to create a helper class that will allow you a point to register more than one registry. Think of it as a middle man to the registration process (this step is not required...but is nice to have). The third is to wire that helper class into the Global.asax Application_Start method (or similar) so that StructureMap works as soon as the application gets started. In the case that you are using StructureMap in your unit tests you will also need to call your Registry class to get StructureMap wired up and running.
Listing 4: Create the registry
The registry allows us to set the default type for a given type. In the registry class we can specify the default type for many interfaces. Next we need to create the middle man class that allows us to wire in as many registers as we might need. Think of this as a point of extensibility.
Listing 5: Registry middle man
This middle man class then allows us a way to wire in multiple registers into our application with one line.
Listing 6: Global.asax.cs
Programatically specifying a type
This last way of specifying what objects you want to play with doesn't really provide a way for specifying your default types (though you could use it for that) but is more for swapping out your default configuration to replace it with something that you need in a given instance. For example, you might have a PostRepository that you want to use in production but while under test you might instead want to use the MockPostRepository for a brief moment, and can then swap back to the default instance from there.
Assuming the default instance of StructureMap is in place (according to the other two methods specified above) the following can be used:
And then when you are done using the MockPostService instance you can then swap StructureMap back to its default using this line:
Refactoring to implement StructureMap
Now that we know the various ways to configure StructureMap we can take a look at how to weave this into our code base. I am going to use the custom Registry method where we create a Registry and Helper class to map StructureMap into the code base. I am choosing to use this method as it leaves the least amount of StructureMap residue on my code thereby allowing me more freedom down the road.
Creating custom Registry classes
Since we took care of creating interfaces for all of our classes and refactoring for Dependency Injection in the last article all we really need to do is map in StructureMap and then use the container to instantiate our objects instead of using a direct dependency method. To start we will create our Registry classes.
Listing 7: CoreRegistry.cs
Notice that this class can be called whatever you like. The important part is that it inherits from the Registry base class. Next, notice that the code is in the constructor of the custom class. From there you can see the StructureMap.Configuration.DSL syntax that is used to set the mappings. Once we have more than one class to be mapped for this area of code we will have more than one mapping in here. If you have bigger areas within your code you might group them further into smaller more specialized Registry classes. Now look at the next segment of code and notice that there are multiple mappings configured there.
Listing 8: DataAccessRegistry.cs
Registering our custom Register classes
Once we have our custom Registry classes we can then create our helper class that will take care of initializing StructureMap for us. We will first look at the RegisterDataAccess class and then the RegisterCore class as it has an example of multiple class initializations.
Listing 9: RegisterDataAccess.cs
Once we have our custom Registry classes created we can then do the actual initialization of StructureMap through its ObjectFactory.Initialize method which allows us to add Registry classes to what StructureMap knows about.
Listing 10: RegisterCore.cs
Notice that adding multiple Registry classes to the actual implementation of StructureMap through the ObjectFactory has to all be done in one call to Initialize. This is a common step to miss. If you add one registry to a .Initialize() call and then add another Registry to a new call to .Initialize() you will end up with only the last added Registry!
Wiring StructureMap to our application
Now that we have our custom Registry classes created and have provided a way to wire them into StructureMap we need to actually wire everything into our application. Since we are working in a web application we will wire up StructureMap through the Global.asax file. If you are using StructureMap in a unit test you might do the same wiring in a setup method. And if you are doing this in a WinForms application you might do this via a Main method or similar call.
Take a look at the new RegisterCore(); call in our Application_Start() call.
Listing 11: Global.asax.cs
That's it! StructureMap is now officially wired into the application. Now we need to actually change our application to take advantage of this super flexible framework.
Using StructureMap
If you read the last article then you will recall that we left off refactoring all of our dependencies up as far as we could. Given that we are using the ASP.NET MVC framework we sort of got stuck when we refactored up to the Controller level. For that reason we will start off there. First we can remove the private field and constructor at the top of the HomeController as those are no longer needed. Then we will make a change to the Index action in the HomeController. Instead of directly instantiating our PostService and getting a list of Posts we will change it to read like this:
Listing 12: HomeController.cs
The key to using StructureMap is the ObjectFactory class that has a bunch of static methods hanging off of it. Generally we will want to use the generic method ObjectFactory.GetInstance<{interfaceName}>() as this leaves it up to StructureMap to return the currently configured implementation of the specified interface. Another important method to be aware of is ObjectFactory.GetNamedInstance<{interfaceName>(key) where key is a specific name of an implementation for the specified interface type. We will see usage for this shortly when we create our custom ControllerFactory.
If you are paying attention to all the details here then you are probably asking yourself how that works? After all we just removed all the hard dependencies to our PostService, PostRepository, and Connection classes. While we sort of wired in a new dependency to the PostService through StructureMap, we totally obliterated all references to the PostRepository and Connection classes. So much so that we can now remove the DataAccess reference that we had to add back to the Web project in the last article.
The reason that this code still works is that StructureMap is aware of the assembly that the Connection and PostRepository live in. More than just that it knows about default mappings for both of those types. And it knows that the PostService has a dependency on this classes because the IPostRepository lives in the PostService constructor and the IConnection lives in the constructor of the IPostRepository. Since StructureMap is aware of all of this little details we don't have to worry about them anymore. Simply by asking the ObjectFactory to get us an instance of something it will take care of all the plumbing and dependency code that we used to have to deal with. This frees us up to do other way more fun things with our time...like creating custom ControllerFactory objects.
Custom ControllerFactory to push all dependencies even further up the stack
The reason that we want to look at how to create a custom ControllerFactory is that most of our code is testable but not all. One sore spot is that our controllers are not currently testable. Since a controller is a very important part of our code that to some degrees which views should be shown to the users of our application it is fairly important that we can test them and what they do. With the default implementation of the ASP.NET MVC framework we lose control at the Controller. That is to say that the framework decides which Controller is invoked. In order for us to apply logic prior to the framework invoking the controller we need to create a custom ControllerFactory and wire that into the MVC pipeline. Then we can inject our types into the Controller from there and more importantly we will be able to test our Controllers after that.
To get started we need to create a custom ControllerFactory. Ours will be called StructureMapControllerFactory and will use the power of StructureMap to return a Controller by its controller type. If StructreMap is handling which controller is passed out to us then it will also handle the constructor dependencies for us too!
Listing 13: StructureMapControllerFactory.cs
Once this is in place we will then need to implement Dependency Injection in our HomeController. A quick refactoring will look something like this.
Listing 14: HomeController.cs
Then, like all of our other major refactorings that involve configuration, we need to tell MVC that we want it to use our custom ControllerFactory instead of its default controller factory. We will do this in the Global.asax.cs as well.
Listing 15: Global.asax.cs
We can finally test our Controller
Now that we have lifted up all dependencies into the world of StructureMap we can inject our dependencies back into our HomeController when testing it. Since we covered most of this in the last article I will simply show the HomeController test here.
Listing 16: HomeControllerTests.cs
A quick explanation for the above code is that we created a MockRepository using RhinoMocks (as described in the last article) to generate a mock for us based on the IPostService interface. I then created some fake test data. We then set up the expected call and told the mock to return the testData when it was called for. Next we told the MockRepository to get ready for action by calling the MockRepository.ReplayAll() method.
Then we switched modes and instantiated a new instance of the HomeController passing in the mocked PostService. We then called the Index method on the HomeController. Finally we tested that the ViewDataDictionary had the list of Posts in it like it should. Running the test showed that all is green!
Analysis
At first glance this dependency graph probably doesn't look a whole lot different from the previous one. In point of fact though there is one major difference. We are once again to t appoint where the web only knows about the core and the domain and nothing else. We can probably tinker with our set up a bit more to remove a few remaining references where they don't need to be by moving all of the interface definitions into our Domain project (which we will eventually do). This would make the Domain the keeper of the keys with regards to what our application expects from one layer or another. We will probably get to this in the next article when we start to look at distributable partitions in the Core tier.

Pros
The big win accomplished by using StructureMap is that we can now have very loose dependencies in our code. Short of being dependent on Domain types there really is no other reason for a direct instantiation of a class of any other kind. This will make our code much more flexible. Having StructureMap in place the way we do would technically allow us to swap out our LINQ to SQL data access layer for any other form of data access. The only thing left to make that sort of flexibility a reality is to push all the interfaces that define what our data access is up into the domain.
Cons
As StructureMap does use Reflection (as does AutoMapper) this could be seen as a performance hit. But I have yet to encounter that scenario in reality. Other than that it does add a bit of complexity for a new comer to wrap their heads around. But given the amount of benefits in the terms of flexible code that StructureMap yields, the benefits out way the costs!
Comparison Chart
Table 2: Comparison Chart
Coding Concepts | Yes | Sorta | No |
Fast/Easy to develop: Can we generate the end product quickly? | X | | |
Testable: Can we write tests around the majority of the projects code? | X | | |
Flexible for refactoring: Can we easily refactor the code base to add new concepts? | X | | |
Well abstracted: Do the users of your code only know what they need too? | X | | |
Well encapsulated: Can you change the internals of code without impacting the users of that code? | X | | |
Separation of concerns? Is your code well compartmentalized and only doing what it needs to? | X | | |
DRY? Does your code follow the "Don't repeat yourself motto?" | X | | |
SOLID? Does this code comply with the SOLID principles? S: Single Responsibility Principle - there should never be more than one reason for a class to change O: Open Closed Principle - should be open for extension but closed for modification L: Liskov Substitution Principle - functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it I: Interface Segregation Principle - clients should not be forced to depend upon interfaces that they do not use D: Dependency Inversion Principle - high level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions. | X X X X X X | | |
Swappable? Can you swap out an entire layer down the road? | X | | |
Distributable? Can you push complex processing of logical areas to a separate server easily to offload computing cycles and scale? | | | X |
Summary
In this article we discussed how we can enhance the power of the Dependency Injection pattern by implementing an Inversion of Control container (IoC). We then discussed what an IoC container can be used for and how it works. Then we looked at implementing an Inversion of Control container in our code. We specifically implemented the IoC container StructureMap. Once StructureMap was plugged in and working we refactored our code to take advantage of the new features and functionalities that StructureMap provides us with. And with that refactoring completed we then addressed the Controller issue that we found in the last article by creating a custom ControllerFactory that took care of locating and returning a controller but also took care of instantiating our dependencies in an automated fashion using StructureMap. We then wrote unit tests around our HomeController demonstrating that our controller was just as flexible as the rest of our code base.
In the next article we are going to look at how distributable our current code base is. We will find that even with all the refactoring and modifications that we have done we are still pretty married to a fairly hardwired infrastructure. If one piece of our code requires more CPU time than any other we can't simply scale out that bit. In the next article we will implement a WCF client and service layer that will allow us to break up our Core tier in just this distributed manner.
About Andrew Siemer
 |
I am a 33 year old, ex-Army Ranger, father of 6, geeky software engineer that loves to code, teach, and write. In my spare time (ha!) I like playing with my 6 kids, horses, and various other animals.
This author has published 29 articles on DotNetSlackers. View other articles or the complete profile here.
|
Please login to rate or to leave a comment.