Hi, in this post I will explain and demonstrate how we can strive for a loosely coupled design for our dependencies in the software application with Dependency Injection (DI) container and the Common Service Locator Library from Microsoft Pattern & Practices group. In other word, we try to achieve loosely coupled design in such as way that the application interacts with the different components it relies on through the component interfaces instead of the component’s concrete dependencies with the help of DI container. So, the architecture will be much more flexible and open to change without having most of the codes need to be modified.
Most of us familiar with the layered approach and may have been practicing it all these while in the software development. The idea of layered approach is to logically separate the application components into groups that represent distinct roles and functionality with the aims to make the application more maintainable and easier to scale out when necessary to improve performance. Generally, an application consists of number of basic layers. The most common is the three layer approach which comprises the data layer, business layer and the UI layer. In this simple three layering scheme, the UI layer talks to the business layer and the business layer talks to the data layer in a one way direction from top to bottom. The same goes to the dependencies that flow the same way with each of the layer being aware of the layer beneath it but the current layer is unaware of the layer above it.
This is a good design technique as it allows the factoring of responsibilities and separation of concerns into multiple layers of a software application. However, if we see it from the testability perspective, how testable of each of this layer when in isolation? We know that there is a direct coupling of upper layer to the lower layer. Take for e.g. the business layer is intimately dependent on the data layer. If the business layer is taking a direct concrete references to the data layer, then it would be impossible to test the business layer in isolation because all the real dependencies of the data layer such as the database and other states have to be ready at the time when the business layer needed to be unit tested. This incurs high cost for practicing Test Driven Development as all the concrete dependencies need to be in a known state such as the database initial data and time spent in running the tests would be significant as accessing external resources such as file and database takes times.
Since we are using the real dependencies during the tests, then those failing tests are hard to be diagnosed as the failure in the business layer may be related to the problem in the lower data layer. Diagnosing the root cause is time-consuming and tedious as testing the business layer alone has to take care of the errors and problems in the lower data layer. Other problem would be the ease of maintenance of the codes. Changes in the lower layer will force the immediate layer above it to be modified in some way due to the implicit and explicit dependencies that the upper layer has on the lower layer.
Dependency Injection Container Comes to Rescue
Based on what I have described, building loosely coupled application/components requires more than just separating the application into its distinctive layer of responsibilities. It requires the effort of programming against the abstraction. Another term for this is programming to contract. The high level component doesn’t depend on the low level component but its abstraction or interface instead. However, programming to contract does not solve the problem completely as the concrete implementations of the dependencies need to be instantiated somewhere in the application. One of the ideal solutions is to make use of the Dependency Injection container to return the concrete implementations. The container centralizes the objects creation for the dependencies and also provides the flexibility to switch among different implementations of the same interface/abstraction without having the client code knowing about it.
Generally, if you read up the definition of Dependency Injection from Wikipedia, it is process of supplying an external dependency to a software component. It is a specific form of Inversion of Control, IoC where the process of getting the dependency is the process being inverted. Hypothetically, a business component makes calls to a service component by instantiating an object of the callee component and it is the responsibility of the business component to take care of the whole life cycle of the instance. With dependency injection, this process is handled by a dependency provider which is also referred to as container in the current trend. The business component will no longer create the instance of the callee but requests it from the container. The container returns a reference to the implementation to the business component so that it can accomplish its task. The container itself knows how to orchestrate the dependent and manage its life cycle. All the boilerplate codes of handling all these are being built into the container itself and the consumer simply request the references. As in most of the containers available nowadays, the types mapping registration is done in the container initialization during run time or through some form of XML file configuration during the design time. Other mean will be through some form of attribute decoration for the type member that need dependency injection. So, the container knows what and how to return the reference to the implementation instance of the requested/target type.
Most of the containers also support automatic dependencies injection in which the container examines the dependencies of the requested type and create those dependencies without requiring the developers to supply them in the code. Normally, we can see automatic dependencies injection in the constructor and property (setter) injection. In constructor injection, the dependent types listed as parameter(s) in the target’s constructor. When an instance of the target type is requested from the container, the container will instantiate all the dependent types in the target type’s constructor parameter(s) and wire them up with the target type instance. In property (setter) injection, the dependent object is instantiated and wired up with the member of the target type. Usually, the member or property of the target type is annotated with attribute that will tell the container the type member that has dependency injection requirement need to be fulfilled.
Factory vs DI Container
At this juncture, I would like make clear that the factory pattern/class has been very popular and it is a common way to provide dependency injection in the component or class to achieve loose coupling. Through this way, the instance of the dependent type or class is constructed and initialized in the factory class and injected into the calling component or class. The factory class is rarely reused outside of the creating component. Its purpose merely serve the dependencies needs of a few related creating components within a particular business domain or a family of calling classes in the class hierarchy. In other words, the factory is a specialized class to serve particular dependency needs. On the other hand, container provides a layer of abstraction to house components. Within the container, it has generic factory classes to instantiate instances of classes.
In fact, container works at a broader level and does more than what factory pattern can offer besides instantiating objects, resolving and injecting dependencies. It allows us to define what type of dependencies to inject into each target type and configure the instantiation mode for each type. For e.g. should a new instance of a type be created every time it is requested or the same instance is reused (singleton). Container itself also provides lifetime management. It keeps references to the objects it instantiates to manage their life cycles, or keep the objects alive for reuse later such as the singleton object. Type or class that is configured to return a new instance whenever a request is made, container will forget their references so that the garbage collector can reclaim their storage. So, Dependency Injection Container/Framework just make it easier.
From other point of view, factory pattern requires the developers themselves to write code for constructing, initializing and wiring up the dependencies. All the factory classes has to come into the picture of the class API design. Whereas, with the Dependency Injection Container/Framework, we outsource all these responsibilities to a third party component which is separated from our application code. With the high level of configurability of DI container, any types of instances can be easily created and configured. The configuration information is placed in a central place for easy modification later. Through the file based configuration, dependencies change can be made without having to recompile the factories.
Anywhere, in a small application with a few types of instance to be created, factory pattern works very well and it is simply to understand. Besides, it provides a great learning experience in designing factory classes in a software application.
Microsoft Unity DI Container (Unity Application Block 1.2) & Common Service Locator Library 1.0
This post is not about what is Dependency Injection in depth. It is about putting it into action with the Unity DI Container. I will demonstrate how to apply the Dependency Injection and Common Service Locator Library to the sample code that I have prepared for my previous post on Repository, Specification, Unit of Work, Persistence Ignorance POCO with Microsoft ADO.NET Entity Framework Beta 2 and Using the Mocking Framework – Moq. The sample application comes with this post won’t be must different from those found in the posts mentioned just now. In fact it is the same sample application with some modifications to demonstrate the purpose of this post. Anyway, prior to completing this post, I have refactored the sample project code and the changes are briefly explained at this post; Repository, Specification, Unit of Work, Persistence Ignorance POCO with Microsoft. ADO.NET Entity Framework 4.0 Beta 2 – Code Update.
You will see the use of DI container, in more specific, the Microsoft Unity DI Container 1.2 to inject life (dependencies) in to the sample application. There are lots of DI containers out there available for .NET platform. To name a few, Castle Windsor, Spring.NET framework, StructureMap, Linfu, Seasar2 Container and etc. Some of these containers have been in existence for over a period of time and well ahead of the Microsoft Unity DI container. I choose Unity container because I have used it before and I am more familiar with Enterprise Library from Microsoft’s pattern and practices group, compared to other open source enterprise frameworks. Other than that, Unity Application Block has a comprehensive documentation and quick starts for beginner.
Besides, you will also see the container abstraction library, Common Service Locator Library being put into use to provide container abstraction. So, you can have your application code to switch among different type of DI container without having it to tie to the specific container. It provides you a way to evaluate each of the available container in term of its performance and how it best fits your application needs before you finally decide the specific container you really want to use. It also fulfills the need of your customer who wants to use different DI container on request. So, it will spare you the need of having to modify your application code to take a different dependency on a particular DI implementation. By relying on the Common Service Locator Library, we can make our application container agnostic. Of course, it will create one more level of indirection which is sometimes not desirable. There are Service Locator and Dependency Injection pattern out there to help us to build loosely coupled components. There are lot of article out there provide full coverage of both. If you are interested to know further and want to contrast Service Locator to Dependency Injection, you can follow Martin Fowler’s article here.
Without much ado, let have a look at the Solution View of the Dependency Injection & Common Service Locator Sample Application in Figure 1.0.
Figure 1.0 Solution View of the Dependency Injection & Common Service Locator Sample Application
Based on Figure 1.0, you will notice that there are four more assemblies in the red rectangle box being introduced in the SharedLibrary solution folder. The assembly Microsoft.Practices.ObjecBuilder2.dll, Microsoft.Practices.Unity.Configuration.dll and Microsoft.Practices.Unity.dll are required for the Unity container to work. Whereas, the assembly Microsoft.Practices.ServiceLocation.dll is the Common Service Locator Library which provides container abstraction. You will also notice Moq.dll assembly which is the library for the Moq object framework that provide mock implementation for the dependencies of the object being unit tested. In our sample application, the CustomerRepository is the object being unit tested. If you are interested to know more on using the Moq, mock object framework, please follow my previous post on Using Mocking Framework – Moq.
You will also notice the UnityServiceLocator C# source file in the solution view. UnityServiceLocator class is the adapter for UnityContainer to the IServiceLocator interface in the Common Service Locator Library. This adapter class is necessary as in our sample application, we no longer code against the specific container interface for Unity, IUnityContainer. Instead, we will code against IServiceLocator interface to access the Unity container’s services indirectly. This avoid hard references to the IUnityContainer and it will allow us to switch different DI containers without changing the code in our sample application as long as we have the adapter for each of the different DI container.
BootStrapper and UnityBootStrapper are used for initialization of the application before the unit tests start. Inside the bootstrapper, it can initialize any global variables and setting or whatsoever that are needed by the rest of the application. In my sample project, I used it to initialize and configure the Unity container instance with the types mapping information stored in the Xml configuration file in a format that is understandable by the Unity. The Unity instance will be used for the rest of my unit tests. You can refer to the Unity Application Block 1.2 – October 2008 chm documentation file for more information on Configuring Containers at Design Time which will tell you all the possibility that the Unity Container can be configured. Figure 1.1 is a snapshot of my Xml configuration information used in the sample project.
The InitializeTestEnvironment contains a public static method, Initialize which is decorated with the Microsoft.VisualStudio.TestTools.UnitTesting.AssemblyInitializeAttribute identities this method to be run before all the unit tests. Within this method, the UnityBootStrapper is instantiated to trigger the initialization.
As usual, the CustomerRepositoryMoqTest contain the unit tests to test the business layer types, CustomerRepository but with its dependency being mocked by the Moq mocking object framework. The CustomerRepositoryTest uses the real dependency for the unit tests. Moq is used to replace the real dependency with the mock object that mimics the behavior of the real dependency and enable us to carry unit tests even without the presence of the real dependency. This is only possible if the higher level api interact with the lower level dependencies via interfaces instead of the concrete or hard references.
Figure 1.1 Snapshot of the Xml Configuration Information Used in the Sample Project.
In the refactoring the sample project codes to use the Dependency Injection Container, I have decided to drop all the factory classes as the Unity container provide object creation and other services that can replace these factory classes. However, there is one exceptional case to the UnitOfWorkFactory. This class is renamed to EntityUnityOfWork factory later in the MyCompany.Data.Entity project. The container is best to use when creating objects that are fixed at design time or without decision-making on what type of object to be created at run time. The EntityUnitOfWork encapsulate the logic for object creation that depends on whether it is in web or non web context. So, it is best handled with the factory classes. Figure 1.2 shows all the factories that are removed in red rectangle box.
Figure 1.2 Solution View for the Factory Classes that are Removed
ObjectContextFactory is removed and is replaced with the ServiceLocator in the AspNetObjectSourceLifetimeManager, ScopeObjectSouceLifetimeManager, StaticObjectSourceLifetimeManager in the MyCompany.Data.Entity project. Figure 1.3 shows how the ObjectContextFactory is used to create ObjectContext instance in the AspNetObjectContextLifetimeManager prior to the code update and Figure 1.4 shows how the ServiceLocator is invoked in the AspNetObjectSourceLifetimeManager to return a new instance of the object context after the code update.
Figure 1.3 – ObjectContextFactory Create ObjectContext Instance in the AspNetObjectContextLifetimeManager
Figure 1.4 – ServiceLocator Create ObjectContext Instance in the AspNetObjectSourceLifetimeManager
The same also goes to the ObjectContextLifetimeManagerFactory where it is replaced by the use of ServiceLocator as in Figure 1.5.
Figure 1.5 – ServiceLocator Create ObjectSourceLifetimeManager Instance in the Constructor of the EntityRepository Abstract Class
The RepositoryFactory has been removed but replaced with the transparent dependency injection technique. What is transparent dependency injection ? It is a coding style where we explicitly define the dependency interface in the class/type constructor letting the outside world know clearly what the dependencies the class/type has. Figure 1.6 shows the dependency for the CustomerRepository class, IRepository is explicitly defined in the parameterized constructor and there is no parameterless constructor. By explicitly defining the dependency in the class constructor, it enables the Constructor Dependency Injection and more specifically, Automatic Dependency Injection supported by the chosen container. Figure 1.7 shows the Unity Container provides the automatic wiring up of dependencies for the CustomerRepository class.
Figure 1.6 – Explicit Definition of the Dependency in the Constructor for Business Layer Type, CustomerRepository
Figure 1.7 – Automatic Dependency Injection for Business Layer Type, CustomerRepository
In Figure 1.7, I have programmed against the ServiceLocator which return the UnityServiceLocator instance through the Current public static property. The UnityServiceLocator has encapsulated the UnityContainer instance through this statement, ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(unityContainer)) which set the ServiceLocator to use the container instance I have passed through the lambda expression; within the UnityBootStrapper. When the GetInstance() method invoked by passing the type parameter, CustomerRepository, the Unity Container will examine the dependencies of CustomerRepository class and create those dependency implementations as necessary based on what we have configured the Container to return during the design time (Xml configuration file) or runtime. Alternatively, we can also manually pass in the dependency instance to the CustomerRepository’s only one parameterized constructor as shown in the commented out statement in Figure 1.7.
By having the dependencies explicitly listed in the parameterized constructor, we can know what dependencies the class/type need by looking at the public signature. If we are using the mocking framework to provide the mock objects for these dependencies, we can simply pass these mock objects to the class being unit tested through its parameterized constructor after the expectation on the mock object is setup. It also save us lot of time to find the class’s dependencies. Figure 1.8 shows the CustomerRepository class under unit testing being passed the mocked implementation of its dependency using Moq Mocking Framework in the CustomerRepositoryMoqTest.
Figure 1.8 – Passing Mocked Implementation for CustomerRepository’s Dependency through Constructor
This will end my post. If you want to know more on the opaque vs transparent dependency, I would recommend you to read the Nikola’s article on Dependency Injection that reveals some of the best practices in his thought. You can download the source code for this post at the Code Download section below.
Code Download : Tame Your Software Dependencies with Dependency Injection & Common Service Locator Library. (This application sample requires Visual Studio 2010 Beta 2/RC that can open C# project. Right click on the above link and choose Save Target As. Rename the extension from .pdf to .zip once you have downloaded the file. Let me know if you have any problem running the code.)
See you in my next post.
Bye and stay tune…
Some Other Readings
1. You can depends on Patterns and Practices
2. Dependency Injection in Libraries