Published: 13 Apr 2007
By: Karl Seguin

Within a project, classes will inevitably rely on each other. In some situations, this coupling can make code difficult to unit test or dynamically extend. A common solution is to this problem is to use a Dependency Injection Pattern. In this article we'll look at how we can leverage the open-source Dependency Injection Framework called StructureMap, within The Code Wiki application.

To find out more about dependency injection and other hot DDD topics such as O/R Mapping, unit testing, mocking and system architecture, check out Karl's free ebook.

About The Code Wiki

The Code Wiki is an open source application meant to be used as a meaningful learning tool for programming practices such as domain driven design and unit testing. The Code Wiki also comes with a freely downloadable in-progress ebook with new chapters being released periodically. Some techniques, such as the use of Dependency Injection frameworks, were left out of The Code Wiki in order to avoid overwhelming readers. This article looks at how The Code Wiki could have made us of such a framework to help improve testability and allow for multiple database vendors to easily plug-into The Code Wiki. You can learn more by visiting http://www.thecodewiki.com/.

About Dependency Injection

Dependency Injection (DI) refers to the practice of injecting dependencies into your code. The common alternative to DI is to simply hard-code dependencies. DI is particularly well suited when the dependency in question provides a service, as opposed to simply having two domain classes interacting with each other (in other words, it probably wouldn't make sense to use a DI for the relationship between a User and a Role). The most obvious example is the dependency that a business layer has on the data access layer. If a User class has a Delete method which interacts directly with the data layer, you might simply do:

There are two significant problems with the above implementation. First, it's impossible to unit test without a functional implementation of the DataStore.DeleteUser function. Secondly, external vendors can't plug into your code to provide their own DataStore.

The Code Wiki uses a simple type of DI to solve the first problem. Without a more solid framework however, it doesn't support any type of extensibility. Dependencies on a service such as the data layer is particularly painful for unit testers which typically want to avoid having to create temporary databases with fake and controlled data. The problem is much worse for practitioners of Test Driven Development since no implementation of the dependency might exist yet. Once you understand the basics of a DI framework, implementing it within The Code Wiki will be a painless affair.

Constructor Injection

Dependency Injection solves both problems by turning the hard-coded DataStore instance into a more dynamic/pluggable implementation. The Code Wiki uses a simple Constructor Injector implementation, which, for the above code, would look like:

We've lessened the coupling by replacing the hard-coded instance with an interface which is passed into the constructor. The Code Wiki takes it a small step further and specifies a default IDataStore implementation if none is present (which makes the DI transparent to any consumers):

Why A Framework?

For The Code Wiki, constructor injection solved the main problem by allowing the injection of mock objects into troublesome couplings to make unit testing possible. However, I recently worked on a system where there were numerous "troublesome couplings," such as a CacheProvider, LogProvider and DataProvider. This quickly became hard to manage via constructor injection. Additionally, as we've already mentioned, constructor injection doesn't really solve the extensibility problem; how does someone add a new plug-in without recompiling the entire application?

StructureMap solves these problems by providing a configurable and queryable framework. StructureMap is lightweight enough to actually improve code readability. That said, the StructureMap homepage has a very wise message:

Do not use StructureMap if an application or process requires little flexibility. The abstraction and indirection afforded by StructureMap is unnecessary and even harmful in simpler systems or processes.
You can learn more about StructureMap by visiting: http://structuremap.sourceforge.net/

StructureMap Example

Continuing with our UserDataStore example, our StructureMap example begins with the StructureMap.config configuration file (StructureMap supports configuration options other than XML, but XML tends to be the clearest from a learning point of view):

The configuration file defines the DataStore instance as the default instance for the IDataStore plugin. This is achieved using the new DefaultInstance element of StructureMap 2.0. In pure StructureMap lingo, we are defining a PluginFamily of type IDataStore with a default concrete plugin of type DataStore. We're also using StructureMap to pass a connection string into our constructor.

If we wanted to add a new "plugin", we could simply compile it into a separate assembly, drop it in the /bin folder and modify the StructureMap.config file.

Now that StructureMap is configured, our User class changes to:

Rather than having to physically inject our dependency into the User class, we simply query StructureMap's ObjectFactory for the default instance. We can also use the GetNamedInstance method to load a plugin by it's key, rather than simply loading the default isntance.

As you might expect, we can also programmatically inject an instance into StructureMap, which is ideal for unit testing purposes:

Using StructureMap within The Code Wiki

With the basics of The Code Wiki, Depedency Injection and StructureMap behind us, we can now look at what changes to The Code Wiki are needed in order to leverage StructureMap. The steps we’ll go over took little more than 5 minutes to complete from start to end.

Of course, the first thing to do is add the reference to the StructureMap.dll inside the CodeBetter.TheCodeWiki project.

The Code Wiki’s StructureMap.config

With respect to this article, The Code Wiki is comprised of two core dependency layers – the domain entities rely on an IWikiRepository implementation which in turn relies on an IDataStore implementation. The StructureMap.config represents The Code Wiki’s actual dependencies:

We've used a DefaultInstance for our IWikiRepository plugin because it isn't foreseeable that we'll need to dynamically extend this functionality. However, notice that we've used the more flexible PluginFamily element for the IDataStore. This means that The Code Wiki could easily be made to run off of a different database, such as MySql or Oracle.

We add our StructureMap.config to the CodeBetter.TheCodeWiki project and, very importantly, change the Copy To Ouput Directory to Copy Always. This last step, which is also shown in the image below, makes sure the .config file is copied to our /bin folder.

StructureMap.Config Property Window

Changing The Code Wiki's Code

We must now replace our constructor injection code with code that uses StructureMap. The Document, Resource, CommentInformation and WikiRepository classes must all be tweaked.

Resource.cs changes from:

To:

Also, we mustn't forget to change the factory methods CreateNewResource which must be changed in a very similar way. The changes to both the Document and CommentInformation classes almost identical to the changes above.

Interestingly, we could opt to remove the constructor injection altogether and change the Resource code to simply be:

The above code might be necessary if we were dealing with multiple injections, but it's far less explicit as things would just seem to "magically" work.

Next we must modify the WikiRepository which depends on an IDataStore. Again our change is very similar to what we just did; however, StructureMap has a very neat auto-wiring feature which'll recursively push in dependencies into a constructor. What that means is that StructureMap will see that the WikiRepository constructor expects an IDataStore instance, and will recognize IDataStore as PluginFamily it is aware of an automatically push in our default plugin. By simply declaring our constructor as follows, StructureMap will automatically wire the right dependency - with no need to declare a default/parameterless constructor:

Fixing our Unit Tests

Since we haven't changed our API, our unit tests, or any of our code for that matter, don't require any changes. We still have constructors/factories which allow us to manually inject our mock dependencies, which is a core requirement of unit testing. If we did remove these methods and relied on the much more implicit query technique, such as:

StructureMap still allows us to easily inject our mock objects using the InjectStub and UnMock/Reset methods. We would first need to change the SetUp and TearDown methods of the dependency tests, which are aptly named XXXDepdencyTests. For example, the SetUp for DocumentDependencyTests would become: While the TearDown would be: We'd also have to remove the dependency injection (since that particular constructor overload would no longer exist):

Conclusion

In this article we looked at what Dependency Injection is and in which situations it might be a useful pattern for yout to apply. We also looked at StructureMap as a DI framework and explored how easy it would be to add it to an existing application, in this case, The Code Wiki.

To learn more visit the StructureMap homepage and The Code Wiki homepage.
<<  Previous Article Continue reading and see our next or previous articles Next Article >>

About Karl Seguin

Karl Seguin is an senior application developer at Fuel Industries, located in Ottawa, Ontario. He's an editor here at DotNetSlackers, a blogger for the influential CodeBetter.com and a Microsoft MVP.

This author has published 8 articles on DotNetSlackers. View other articles or the complete profile here.

Other articles in this category


Introduction to StructureMap
Have you heard of StructureMap, generally know what it’s for, and want to know how to get started qu...
The Command Pattern
In this article I will provide a quick refresher on what the command pattern is used for, how it wor...
DI Patterns: Constructor Injection
In this article, an excerpt from the book "Dependency Injection in .NET", we will take a detailed lo...
TypeMock’s Arrange-Act-Assert
Brian Mains discusses how to implement the Arrange-Act-Assert pattern in TypeMock.
Key Process Patterns
This article, based on chapter 2 of Specification by Example, presents effective patterns for softwa...

You might also be interested in the following related blog posts


Animating the RadWindow control for Silverlight and WPF. read more
Generic WPF Drag and Drop Adorner read more
Animation Hack Using Attached Properties in Silverlight read more
Framework Design Guidelines: Dependency Properties read more
Putting the Silverlight Layout System to Work read more
Debugging Dependency Properties in WPF with Property Changed Callbacks (or: How I Learned to Stop Worrying and Love printf Debugging) read more
Silverlight Dependency Properties read more
WPF: Read-only Dependency Properties read more
Microsoft gets Design For Testability with new MVC framework for ASP.NET- Finally. read more
Dependency Injection Revisited read more
Top
 
 
 

Discussion


Subject Author Date
placeholder Well written! AndyNil ! 4/18/2007 9:47 PM
There's nothing about how to use StuctureMap Ostrovia Hi 7/21/2008 1:28 PM
placeholder RE: There's nothing about how to use StuctureMap Karl Seguin 7/21/2008 5:36 PM
Check it out Karl Seguin 7/21/2008 5:35 PM

Please login to rate or to leave a comment.

Free Agile Project Management Tool from Telerik
TeamPulse Community Edition helps your team effectively capture requirements, manage project plans, assign and track work, and most importantly, be continually connected with each other.