In the following text we will use a number of terms and diagrams that perhaps introduce some complexity, you may not have come across these terms before so I will take a moment to try to explain them.
- Composition : Aggregation / Aggregated Object – When we talk in terms of object composition what we are really saying is that the final object graph is made up of many objects coming from one root object. To put this another way is to say that an object can contain one or more objects and that these make up the fully composed object. This in its simplest terms is what we refer as object composition.
However there is a subtle variant of object composition called object aggregation, although these are quite often used interchangeably, they are not strictly the same.
Composition is generally used when the object creates the instance of the object being made part of its composed child model. Thus when the root composing object lifeline is terminated, or to put this another way when the root object is destroyed then, the associated child objects which make up the rest of the object graph are also destroyed.
Aggregation differs from object composition in that an object which is aggregated generally has an independent lifeline, and we find quite often it is shared between many objects which aggregate it by reference as part of their object graph. We can therefore say that an aggregated object generally is not explicitly destroyed when a class using that object is destroyed.
- Patterns: Separation Of Concerns and Single Responsibility Principal – Separation Of Concerns otherwise referred to as a [SOC] is a core principal by which we simply state that we should separate our concerns within the application. Traditionally this has involved a horizontal style of separation, or more correctly separating along technical boundaries. If we try to define the MVC pattern in these terms we could say that only presentation logic would be placed in a View. Consequently we could also say that data validation should be placed in the model, and finally we could say that the only place decision logic should be found is in the Controller. [SOC] has a sister pattern known as Single Responsibility Principal or [SRP], when this is applied we say that one class, one operation should only do one thing. This can be scaled to also say one assembly should have a single responsibility, although this is a little abstract and contentious.
Since the emergence of modern architecture principals, [SOP] and [SRP] have been used to identify vertical separation of concern. Taking this into consideration, while applying a Service Orientated Architecture [SOA], we can say that each service has a distinct responsibility. For instance, a ‘Security Service’, or an ‘Order Service’.
The tools we are using
Our own development setup is as follows:
· Visual Studio 2012 http://www.microsoft.com/visualstudio/11/en-us
· Resharper 7 http://www.jetbrains.com/resharper/whatsnew/index.html
· NUnit http://nuget.org/packages/nunit
· NUnit Fluent Extensions http://fluentassertions.codeplex.com/
· NSubstitute http://nsubstitute.github.com/
We find that the above combination of software packages makes for an exceptional development environment. Windows 8 is by far the most productive Operating System we have used across any hardware stack. Jet Brains Resharper has become an indispensable tool, without which Visual Studio feels highly limited. NUnit is our preferred testing framework, however you could use MBUnit or XUnit. For those who must stick with a pure Microsoft ALM experience you could also use MSTest.
We also use a mocking library; in this case we have used NSubstitute due to its power and simplicity. However there are other options available with the same functionality, such as Moq, and Rhino Mocks. We feel libraries like Type Mock should be avoided due the lack of respect for the black box model, this lack of respect allows developers to take short cuts which invalidate good practises.
What Is Inversion of Control [IOC]?
IOC is the practise of inverting the control of a given object. Typically in a scenario that does not use IOC an object is constructed and used by an Aggregating object. The diagram below demonstrates the aggregated relationship.
One of the main aspects of the IOC scenario is that we invert the construction of the Object. In real terms this means that the object is constructed externally to the aggregating object. Inverting the creation of an object through constructing it prior to its use by the consuming / aggregating object has a number of advantages, some of which are listed below:
- Object initialisation can be controlled and the object’ state can be more carefully provided for.
- The object can be registered with an external collection.
- We can keep a reference or hook externally to the constructed object without violation of black box principals.
- The constructed objects events can be wired up to an external object. This is especially useful for the implementation of various patterns, such as the Visitor and Observer patterns.
We can see below a classic representation of composition by in object instantiation –
“That ‘Object A’ creates an instance of ‘Object B’”
What is wrong with the shape above?
The shape above, with Object A instantiating then subsequently aggregating and encapsulating Object B, leads to a scenario were Object B is hidden from the outside world. This leads to a number of issues and we will examine these in a moment. First let us just note that there are two other solutions to this issue which we list below. These fit outside the IOC / DI pallet, and this article will not attempt to address or discuss them as they are outside its scope.
- Service Location Pattern
- Invalidation of Black box hiding principles. by publically exposing the object
It is worthy of note that there is a huge debate raging about the value of the Service Location Pattern and it is one we have no intention to enter into currently.
Both the solutions above have a tendency to lead to bad practises. The danger when these techniques are used incorrectly is that it can lead to the invalidation of two other very important principals.
- SOC : Separation Of Concerns
- SRP : Single Responsibility Principle
Dynamic operation invocation dependent on runtime conditions
One of the issues IOC / DI helps to address is needing to decide which object or block of functionality we should invoke dependent on runtime conditions.
This is a huge issue with direct instantiation of aggregated objects. Let us think about a situation where we have to make a different operation call dependent on some condition, let us for a moment assume it is a condition that is only available to us at run time. We can in fact see this expressed by the following code fragment below.
The code above highlights the situation where a class has to make a decision about which service to call dependent upon a value that is only available at run time. As we can see the contract signatures of the two classes are the same, so effectively the aggregating class is having to instantiate two objects where it only needs one, and making identical calls to one or the other based upon logic which is outside its SOC responsibilities.
The principal difference between the two code examples is that creational control of the DataService being ultimately used by the ManagerService, or in context of this article the Aggregating class, has been Inverted and moved outside the ManagerService. The effect of this is that the class maintains clean, simple code which is in line with the SOC principal when applied in this context.
How do we apply Inversion of control using Dependency Injection?
Working with inversion of control we have to consider how we pass an object, which we have inverted the construction of, into the intended aggregating object. In this section we will consider Dependency Injection and how this resolves and satisfies this requirement.
We can see in the code sample in the last section that we injected the Object to be used via a parameter on the constructor. This is often referred to as constructor injection. There are in fact two common dependency injection implementations:
- Constructor based injection Constructor based injection involves declaring the dependency by its interface on the constructor parameter list, we show a small example below.
In the example above, we can see that an object at runtime which corresponds to the IDataService interface needs to be injected into the constructor of the ManagerService. When injected into the constructor at object construction, the service is then stored for later use in an immutable class level field.
This is a classic example of Constructor based Dependency Injection.
- Setter based injection Setter based injection methodology has fallen out of favour in modern codebases because this injection technique is, by default, non-mandatory. This is opposed to Constructor based injection which insists that its parameters are satisfied at point of construction. However setter based injection is still a valid method and therefore we shall show an example of this below.
The above code shows an exposed setter which has been set up as a Dependency Injection target. In this case we have used Microsoft Unity’s Dependency Attribute to illustrate the property as a Setter injection target, we will talk about injection containers in more depth shortly. In this scenario we can see that the outside system can inject a dependency via a setter – depending on the injection container or composition system being used we can enforce a dependency or mark it as optional.
Setter based injection has been utilized quite often for setting up defaults across an object, the issue with this approach is that it quite often hides bad design choices. We would like to suggest that setter based injection should only be considered if constructor based injection is not appropriate, or if you find yourself in a specialised situation such as utilising MEF [ http://mef.codeplex.com/ ] for View Model / Model injection.
In this short section we have taken a quick tour of dependency injection, and the two methods commonly used to expose dependencies as injection targets. We shall now move on to the real world use of DI and IOC and start to talk about containers and how they empower these principals and provide immense power and flexibility to our codebases.
IOC and DI in the Real World
When designing a modern application using concepts such as Emergent Architecture and some form of test driven development, it becomes a natural process to utilise design principals such as SOC and SRP, this will often mean that we end up with large object graphs which would be inconvenient to manually inject into objects.
Modern development teams utilize IOC Containers such as those listed below
- Ninject [ http://www.ninject.org/ ]
- Unity [ http://unity.codeplex.com/ ]
- Autofac [ http://code.google.com/p/autofac/ ]
- Structure Map [ http://docs.structuremap.net/ ]
We will utilize Microsoft Unity as our container for the rest of this article, Unity is a very capable IOC container and is trusted by many world class development teams and in certain camps is seen as the standard which other containers need to meet.
Microsoft Unity supports both Setter Injection and Constructor Injection. We have discussed some of the issues with Setter Injection and due to these issues, the rest of this article will focus on Constructor Injection using the Unity Container.
Let us now Test Drive a simple example using ASP MVC. We will produce an application which makes use of Unity and some community extensions which provide the binding bridge between ASP MVC and the Unity IOC container.
ASP MVC Example
We will now build a trivial application which utilizes
- The concepts expressed so far in this article
- The Unity Framework
- The ASP MVC Framework
- Visual Studio 2012
- Resharper 7
- NUnit Fluent Extensions
The application will demonstrate a Specification Driven ASP MVC controller. We will utilize SOC by separating our business functionality from our presentation framework. Our final deliverable application will wire in a Unity container with any needed frameworks to provide a working application.
The purpose of the application will be to Base64 encode text fragment.
We start with a test
As always with modern development in an emergent setting we start with a test.
Writing the test above generated an ASP MVC project within which the following artefacts are of interest to our discussion.
The controller shown below has a dependency on the IEncoderService, in our case we are passing in a Base64 Encoder service. We could use the same controller to encode to anything we please just by changing what we pass into the constructor. Below, for your reference, is the base64 encoding service and model.
Once the test has been completed and is passing thusly.
Then it is simply a matter of running the website to see what we need to do next.
We receive an exception page when we ask the ASP MVC framework to load the view, this is because the framework is trying to create the controller. However because we are making use of Dependency Injection and injecting the EncoderService into the controller, the framework can only find a parameterised constructor and therefor is unable to create an instance of the controller. Thus we need to give the framework a little help.
Fixing the Application
Step 1: We now need to bring in a ASP MVC Bridge to Unity, we could hand-code this but Nuget already has a useful package [Unity.Mvc3] in it is repository which supplies the functionality we need.
Step 2: With the Unity MVC 3 package in place, we now need to tell the application how to use it fortunately we find it has added a Readme file to our solution, within this file we find the following text.
“To get started, just add a call to Bootstrapper.Initialise() in the Application_Start method of Global.asax.cs and the MVC framework will then use the Unity.Mvc3 DependencyResolver to resolve your components.”
As directed above we will now insert a call to the Bootstrapper into the Global.asax
Step 3: With Bootstrapper registered construction is now delegated via the UnityDependencyResolver. This uses the Unity Container, in which we have not yet registered the IEncoderService Interface against concrete implementation, thus we now see a new error when we try to run the site.
Step 4: Is to follow the guidance in the error message and add an implementation for the interface (IEncoderService), which is expressed as a dependency on the controller we are trying to construct. Lets do that right now.
We have now registered the IEncoderService with the container and told it that the EncoderServiceBase64 is to be injected into any object requiring an implementation of the IEncoderService. In addition we have told the container to use a ContainerControlledLifetimeManager, which means that we will share the same instance of the EncoderServiceBase64 service across all instance that require it, this in effect is a Singleton Pattern implementation [ http://en.wikipedia.org/wiki/Singleton_pattern ].
Finally let us now rerun the application and see if we are exception free.
The View source is below
Let us now enter some text to Base64 Encode
If we submit this query we can see that we hit the breakpoint I have set in the injected Encoder Service. This proves that Unity has composed the Controller for us as expected.
Let us continue with the application execution and hopefully see the end result of the encoded operation.
The View source is below
This article has covered a lot of ground and introduced a lot of new concepts, ultimately the point of development is producing good quality software that can be expanded and maintained with relative ease, while IOC and DI are not the complete answer they do form part of the solution. IOC and DI should be in every professional developer’s toolbox we hope this article has demonstrated both the theory and the real world power of Inversion of Control and Dependency Injection.