.NET and me Coding dreams since 1998!

25Feb/082

Design for Testability – Structure map (Part 6)

On my quest to design for testability, I've already covered:

(In case you don't know what Inversion of Control (IoC) containers are, I advise you to take a peek at Part 4 of this series first before continuing  with this article.)

Today's post will cover what IoC looks like when using StructureMap, which was developed (and is maintained) by Jeremy D. Miller, The Shade Tree Developer. In this post, I'm using the current production version (2.0). Once version 2.5 is published, I'll cover it in separate post.

In contrast to Castle Windsor, the StructureMap framework only contains a lightweight IoC container without any additional unrelated parts. You can download the zip file containing StructureMap here. After you unpack the zip file, simply add a reference to "StructureMap.dll" to start using it.

Summary of the changes required by StructureMap

Once again, I will use the same code from Part 3 (manual DI based on internals) and transform it with StructureMap to something very similar to the Windsor example in my previous post. All the internals will be removed and DI injection will be replaced with service locator. Components will pull in their dependencies from a "well-known-object" implementing the Service Locator design pattern.

Something like this:

 image_thumb2

(All of the types are contained in the assembly "UserManager.dll" and their name space is Example.UserManager. The solution also contains a Console application which calls the UserManager method to illustrate how to use the Service Locator in production.)

As you can see, we now have three fully separate types without most of the DI plumbing code and which we locate (when needed) by using the built-in functionality of the Castle Windsor DI framework.

A major difference between the code in this example and the code in the Windsor example is that the StructureMap framework provides a built-in service locator facade type, so you don't need to write the ServiceLocator type yourself.

Another major difference between StructureMap and Castle Windsor is that StructureMap supports attribute-based definition of container components without any configuration files, which can be a major advantage for people who don't want to dig into the bowels of XML configuration files.

StructureMap container configuration

Most of IoC containers are based on same concepts:

  1. using an interface to define an abstraction,
  2. having concrete classes implement that abstraction,
  3. and providing the IoC container with a mapping between the abstractions and their implementations.

In the StructureMap framework, abstractions are called "PluginFamilies" or "PluginTypes" and concrete implementations are called "Plugins" or "PlugedTypes".

There are three different ways of providing StructureMap with the mapping information it needs to perform as an IoC container:

  • Configuration based implementation
  • Attribute based implementation
  • Manual IoC definition

Configuration based implementation of StructureMap

In a configuration based approach, StructureMap works almost the same as Castle Windsor. During the application initialization, StructureMap reads the configuration file (by default the name of configuration file is StructureMap.config) and gets the list of mappings between the interfaces (PluginFamilies) and types that implement the interfaces (Plugins).

The configuration file can be written in a few ways. In my example, I only have a single Plugin (instead of multiple types implementing the same interface). For this type of mapping, the easiest way to write the configuration file is to use the DefaultInstance element.

The configuration file looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<StructureMap>
  <DefaultInstance 
    PluginType= "Example.UserManager.IUserManager, UserManager" 
    PluggedType="Example.UserManager.UserManager,  UserManager"  
    Scope="Singleton"
  />
  <DefaultInstance 
    PluginType ="Example.UserManager.IUserProvider, UserManager" 
    PluggedType="Example.UserManager.UserProvider,  UserManager" 
    Scope="Singleton"
  />
</StructureMap>

It is quite obvious what this configuration file does: Inside the UserManager assembly, there is UserManager type which implements the IUserManager interface. Also, inside the same assembly, there is a UserProvider type which implements the IUserProvider interface. In both cases, we define the scope as Singleton so that StructureMap container will construct the type instances only once.

The very simple DefaultInstance based configuration is not suitable if multiple Plugins implementing the same interface. You can see a more complex (but more powerful) configuration file content with PluginFamily, Plugin and Instance elements in this blog post.

Attribute based implementation

For those (like myself) who are not so keen on writing XML configuration files, StructureMap provides another way of defining IoC container components. Instead of reading values defined in a configuration file, StructureMap performs reflective attribute inspection of the given assemblies and registers all interfaces decorated with [PluginFamilyAttribute] and all the types decorated with [PluggableAttribute].

The end result of either the configuration file or the attribute inspection is the same: StructureMap IoC container gets all the necessary mapping information.

Let's take a quick look at an example of IUserProvider and UserProvider (a link to complete example is at the bottom of this post).

Marking an interface as PluginFamily looks like this:

using System.Collections.Generic;
using StructureMap;

namespace Example.UserManager
{
    [PluginFamily("userProviderService")]
    public interface IUserProvider
    {
        IList<User> GetUserCollection(string userName);
    }

I've decorated IUserProvider with a PluginFamily attribute specifying that the Plugin with key userProviderService is the default implementation.

And this is how the Plugin would be defined:

sing System.Collections.Generic;
using StructureMap;

namespace Example.UserManager
{
    [Pluggable("userProviderService")]
    public class UserProvider : IUserProvider
    {
        public IList<User> GetUserCollection(string userName)
        {
            // return something from DB
        }
    }
}

I've decorated the type which implements the interface (previously defined as PluginFamily) with the Plugin attribute, and provided a concrete lookup key for this implementation. As the key value is the same one used in the definition of the PluginFamily, UserProvider will be instantiated when the StructureMap retreival method is called (unless the key name of another desired plugin were provided to the retrieval method).

Now that we have the appropriate services and types decorated, all we need to do during the application startup is to tell StructureMap which assemblies it should inspect to collect services and concrete types. The code for doing that would look something like this:

            // turn off config file
            StructureMapConfiguration.UseDefaultStructureMapConfigFile=false;
            // collect components from the assembly containing IUserManager
            StructureMapConfiguration.ScanAssemblies()
                .IncludeAssemblyContainingType<IUserManager>();

After disabling the configuration file, I instruct StructureMap to scan the assembly containing IUserManager (which is UserManager in this example). As a result, StructureMap will register all the services and types exactly the same as the configuration file example.

Manual definition

In some cases, we might want to stay away from configuration file but adding attributes is not a viable option (e.g. we don't own the source code or we don't want to introduce a dependency to StructureMap). In these cases, we can take control from StructureMap and perform the appropriate container mappings on our own.

As an example, consider a test method that is supposed to test UserManager (which has a dependency on UserProvider) . My personal preference in writing tests is not to be depend on special - "test" configuration files, so instead I use a helper method for manual registration. The code is similar to this:

        private static void SetUpServiceLocator(I instance)
        {
            // 1. turn off configuration reading
            StructureMapConfiguration.UseDefaultStructureMapConfigFile = false;
            // 2. register a mapping between the service and type into the container 
            StructureMapConfiguration.BuildInstancesOf(I);
            // 3. inject mocked instance
            ObjectFactory.InjectStub(typeof (I), instance);
        }

Method signature defines constraint that "T is I". The input parameter passed to this method is a concrete instance of a type which has to be retrieved later upon any request for "I" service.

In first line of the method StructureMap is instructed not raise an exception if the configuration file is  missing. After that, the service - type mapping is defined. Once the mapping definition is complete, StructureMap is instructed to register the provided instance so that the query to StructureMap for an instance of I will return that instance.

ObjectFactory

Regardless of how the StructureMap configuration is done (configuration file, attributes or manual approach), service location is the same. StructureMap already contains a built-in facade/service locator class, so there is no need to build those on your own (like I did in the Windsor example).

ObjectFactory has two major static methods used in service retrieval:

  • T ObjectFactory.GetInstance<T>();
  • T ObjectFactory.GetNamedInstance<T>(string concreteKey);

As you can tell from signatures, GetInstance method retrieves the default implementation of the service of type T, while GetNamedInstance allows you to pick a specific service implementation.

In this little example, we have a single service implementation so we use the ObjectFactory.GetInstance call:

using System;
using System.Collections.Generic;
using StructureMap;


namespace Example.UserManager
{
    [Pluggable("userManagerService")]
    public class UserManager : IUserManager
    {
        #region IUserManager Members
        public int NumberOfUsersActiveInLast10Days(string userName)
        {
            IUserProvider _userProvider
                = ObjectFactory.GetInstance<IUserProvider>();
            IList<User> userCollection
                = _userProvider.GetUserCollection(userName);

            int result = 0;
            foreach (User user in userCollection)
            {
                if (user.LastActivity > DateTime.Now.AddDays(-10))
                    result++;
            }
            return result;
        }
        #endregion
    }
}

 

The only interesting thing in this example (compared to the previous Windsor post) is that I have used StructureMap's built-in SeviceLocator class ObjectFactory.GetInstance<IUserProvider>() to retrieve an instance of  UserProvider implementing the IUserProvider interface. In the Windsor example, I had to build the Service locator on my own.

Note: I am aware of the general concern about having opaque dependencies in this example and I plan to tackle that important question in separate post, so there's no need to criticize me on that (at least not here :-) )

Writing unit tests using StructureMap DI framework

Writing tests with StructureMap is very simple and based on usage of InjectStub method already described in the manual configuration definition section above.

So, to test the business logic in NumberOfUsersActiveInLast10Days, I would need to mock the UserProvider dependency (to prevent DB calls that class does) and then just test the business logic. That would look something like this (same test as in previous blog posts):

         
	[Test]
        public void GetActiveUsers_TestCaseOfZeroUsers()
        {
            using (mockRepository.Record())
            {
                IUserProvider userProvider
                    = mockRepository.DynamicMock();
                Expect.Call(userProvider.GetUserCollection(null))
                    .IgnoreArguments()
                    .Return(new List());

                SetUpServiceLocator(userProvider);
            }
            using (mockRepository.Playback()) 
            {
                IUserManager _userManager = new UserManager();
                int count = _userManager.NumberOfUsersActiveInLast10Days("M");
                Assert.IsTrue(count == 0);
            }
        }

Interesting aspects of this test are:

  • Usage of new explicit Record/Playback model of writing tests using RhinoMocks (previous Windsor post was based on implicit recording model).
  • The first two commands are an example of using RhinoMocks to create a mocked instance of a given interface and to state required behavior for this test (there are no users retrieved from database).
  • The injection of the mock to the StructureMap IoC container is performed by the SetUpServiceLocator method (described above).

What's next?

The purpose of these DFT blog posts is just to give a How-To quick start. To get more information on StructureMap, I recommend the following links:

Source code of the small example presented in this post can be found here

[edited by cbeauvais]

Filed under: Uncategorized 2 Comments
20Feb/085

Design for Testability – Castle Windsor (Part 5)

Pursuing the quest of Design for Testability, we've already covered:

(If you don't know what Dependency Injection (DI) Frameworks/IoC containers are, then I advise you to take a peek at Part 4 of this series first.)

The last episode covered the basic concepts of the DI frameworks, so today's post will present how those concepts are implemented in a DI framework named Castle Windsor.  Castle Windsor is the open source Inversion of Control (IoC) container piece of the Castle Project, which also contains ActiveRecord and MonoRail. There is only one installer for all three parts. Download it from the Castle project web site and install it to your GAC.
After installation, all you need to do to use Windsor is "Add reference..."  to: Castle.Windsor, Castle.Core and Castle.MicroKernel assemblies. 

Summary of the changes caused by Castle Windsor

Today's post will cover the same example I've used in previous DFT blog posts. This DI framework requires some changes to the code structure (although the functionality stays the same).

So, we are starting with this:

With this DI framework, we no longer need the internal properties, replacing them with Castle service locator calls. So the static diagram of the Castle solution looks like this:

image

(All of the types are contained in assembly "Windsor_Example.dll" and their name space is Example.Windsor. The solution also contains a Console application which makes a test call to the UserManager method.)

Summary: We have now three separate types withouth most of the DI plumbing code. Each type will locate the services it needs by using the built-in functionality of Castle Windsor DI framework.

Now, let's dive into the details of how this change is implemented ...

XML configuration

Windsor is a configuration-based DI framework, which means that the application's configuration file has to contain all the settings that the Windsor service locator requires.

Structure of a Windsor configuration file

The Windsor configuration information can be stored either in the default configuration files (App.config, web.config) or in it's own XML configuration file. In either case, it has to include:

  • the definition of the castle Windsor configuration section
  • Inside this section, a collection of components, each of which contains these three elements:
    • id (a key which can be used by the service locator to find an appropriate component to inject)
    • service (which describes the contracted behavior of the component - usually an interface)
    • type (which contains the component that implements the service contract - usually a class that implements the service interface)

The configuration file for our little example is contained in the App.config file of the console application. It looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="castle"
			type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor"/>
  </configSections>
  <castle>
    <components>
      <component id="userProviderService"
		service="Example.Windsor.IUserProvider, Windsor_Example"
		type="Example.Windsor.UserProvider, Windsor_Example"/>
      <component id="userManagerService"
		service="Example.Windsor.IUserManager, Windsor_Example"
		type="Example.Windsor.UserManager, Windsor_Example"/>
      <component id="companyManagerService"
        	type="Example.Windsor.CompanyManager, Windsor_Example"/>
    </components>
  </castle>
</configuration>

As you can see, I first define the castle configuration section and then, inside of that section, I have listed all the components contained inside the DI Framework container. The first two components are defined with service and type, while the third component (companyManagerService) is defined only by a type without a service (CompanyManager does not implement any interfaces). Both the type and service attributes contain fully qualified NET type names given in the format "namespace.type, assembly".

Reading the Windsor configuration file

If the Windsor configuration settings are defined in the default application configuration files, it can be accessed like this:

IWindsorContainer _container = new WindsorContainer(new XmlInterpreter());

We create a DI container by passing an instance of the XMLInterpreter to the Windsor container's constructor. This will enable the castle service locator to properly retrieve the desired type.

 

Alternatively, if we wanted to store our castle configuration settings in a separate configuration file (e.g. CastleConfig.xml), it can be accessed like this:

IWindsorContainer _container = new WindsorContainer(new XmlInterpreter("CastleConfig.xml"));

The only difference is that we have to provide a configuration file name to the XmlInterpreter constructor. The content of configuration file is the same regardless of where it is stored.

Different ways to locate a service

There are a few ways to locate a service. This example illustrates 3 of them (you can use intellisense to find others):

	IWindsorContainer _container = new WindsorContainer(new XmlInterpreter());

	IUserManager _userManager;
            
	//generic default service retrieval
	_userManager = _container.Resolve<IUserManager>();

	//service retreival only by given id
	_userManager = (IUserManager)_container.Resolve("userManagerService");

	// generic service retrieval for given id
	_userManager = _container.Resolve<IUserManager>("userManagerServiceA");
	_userManager = _container.Resolve<IUserManager>("userManagerServiceB");

In first example, I retrieve an instance of the user manager by calling the generic form of the container's Resolve method. If multiple components had the given service, the first one would be retrieved.

In the second example, the instance is located for a given id (note that it has to be cast).

In the third example, I retrieve a specific component. This is useful when you have multiple components that implement the same service. We could use this to implement the Strategy pattern.

Service Locator / Facade

From a performance perspective, it is critical that the container initialization occurs only once.

From architecture perspective, we would like to avoid having every solution dependent on Castle Windsor.

We can use the Facade design pattern to solve both problems.

 

This implementation uses a separate assembly which contains a singleton private container instance and some public methods (which delegate their calls to the appropriate container methods). The code looks like this:

using Castle.Windsor;
using Castle.Windsor.Configuration.Interpreters;

namespace Facade
{
    public static class ServiceLocator
    {
        private static IWindsorContainer _container 
            = new WindsorContainer(new XmlInterpreter());

        public static void Clear()
        {
            _container = new WindsorContainer();
        }

        public static T Resolve<T>()
        {
            return _container.Resolve<T>();
        }

        public static void AddInstance<T>(object instance)
        {
            _container.Kernel.AddComponentInstance<T>(typeof(T), instance);
        }
    }
}

So we see that ServiceLocator is a static class containing the singleton instance of the Windsor container in a private field. The container has been initialized to a set of types defined in a configuration file.

There are three public static methods exposed:

  • Clear - removes all the container components created from the configuration file (this will be used in tests)
  • Resolve<T> - retrieves the instance of desired container component
  • AddInstance<T> - adds a component based on the type instance to the container.

External usage of those methods doesn't require references to the Castle dlls and we get the performance of a singleton container.

Service location

Now that we have explained how service location works, let's take a look at how we would use the Facade ServiceLocator class.

using System;
using System.Collections.Generic;
using Facade;

namespace Example.Windsor
{
    public class UserManager : IUserManager
    {
        #region IUserManager Members

        public int NumberOfUsersActiveInLast10Days(string userName)
        {
            IUserProvider _userProvider = ServiceLocator.Resolve<IUserProvider>();

            IList userCollection = _userProvider.GetUserCollection(userName);
            int result = 0;
            foreach (User user in userCollection)
            {
                if (user.LastActivity > DateTime.Now.AddDays(-10))
                {
                    result++;
                }
            }
            return result;
        }

        #endregion
    }
}

If you compare this code with code presented previously in this blog series, you will notice that instead of injecting a dependency into the class through a constructor or setter property, we have now a self-contained method that does not depend on external variables. All this method does is call the "well-known" ServiceLocator type to resolve its dependencies. The rest of the code is exactly the same as in previous posts.

Writing unit tests using Castle Windsor DI framework

The only thing left is to write unit tests with mocks. The approach here is similar to standard mock testing:

  • create a mock instance using Rhino mocks
  • replace the real component with the mocked instance in the container
  • verify the expected behavior

So, if I would like to test the business logic in NumberOfUsersActiveInLast10Days, I would mock the UserProvider dependency (which is reading out the DB for values) and then just test the business logic there. That would look something like this (same test as in previous blog posts):

        [Test]
        public void GetActiveUsers_TestCaseOfZeroUsers()
        {
            IUserProvider userProvider 
                =  mockRepository.DynamicMock();
            Expect.Call(userProvider.GetUserCollection(null))
                .IgnoreArguments()
                .Return(new List());
            
            //registering the mocked instance as container component 
            ServiceLocator.Clear();
            ServiceLocator.AddInstance(userProvider);

            mockRepository.ReplayAll();

            IUserManager _userManager = new UserManager();
            int count=_userManager.NumberOfUsersActiveInLast10Days("M");
            Assert.IsTrue(count == 0);
        }

 

Creating a mocked instance is pretty obvious. The new thing here is that I am calling the ServiceLocator.Clear method to get rid of the real user provider constructed in the container from configuration values. Once I have cleaned the container, I add the mocked instance. Now the container will return the mocked instance of IUserProvider to all the code asking for it. (The same thing could be done by using the AMC - Auto Mock Container, but I plan to dedicate a separate post on that subject, so I'll use the manual approach here.)

Once the container has been set up, the rest of the test is the same as when you use manual dependency injection.

What next?

The purpose of this blog post is not to go too deep into the details on Castle Windsor; it is more to give a concise overview of concrete steps for using this framework. For more information on Castle Windsor, I recommend these links:

Source code of the example presented in this post can be found here


Quote of the day:

When you encounter seemingly good advice that contradicts other seemingly good advice, ignore them both. - Al Franken

[edited by cbeauvais]

Filed under: Uncategorized 5 Comments
13Feb/080

Design for testability – Dependency Injection Frameworks (Part 4)

I've been away a while (mostly due to vacation time), but I am back and switching gears from NET foundations to TDD subjects. Although I have prepared material for another "How-To Rhino mock" post I would first like to extend my blog post series on how to build software in a way which enables effective TDD.

Therefore, today's post will continue the Design For Testability (DFT) blog posts in which I already babbled about how to design for testability by effectively utilizing the dependency injection pattern on a simple starting example containing mixed DAL code, business code and cross-cutting concerns code:

My next couple of posts in DFT series will cover the same example from the perspective of using a dependency injection framework (which is based on the service locator design pattern):

  • Part 4 - Design for testability - Dependency Injection (DI) frameworks  (this post)
  • Part 5 - Design for testability - Castle Windsor dependency injection framework
  • Part 6 - Design for testability - StructureMap (v2.0) dependency injection framework
  • Part 7 - Design for testability - ObjectBuilder (v1) dependency injection framework

Also, I plan to cover upcoming revisions of DI frameworks as soon they are available somewhere for download (they are unavailable today)

  • Part 8 - Design for testability - Structure Map (2.5) - once it is available for review
  • Part 9 - Design for testability - Unity Dependency Injection Container   - once it is available for review

Setting the stage

At the end of the exploration of the dependency injection based solution (part 3), we ended up with a solution based on Registry design pattern in which we have a DALRepository static class exposing the singleton instance of CompanyManager class which has an internal property UserManager implementing a poor man's dependency injection of the UserManager instance. UserManager also has a UserProvider internal property which  (by default) gets injected with an instance of UserProvider. Something like this:

image

Testability design criteria was achieved by using the InternalsVisibleTo attribute and exposing the internal property setters to unit fixture assemblies so the test methods could easily inject mocked instances of the UserManager/UserProvider to decouple the test from unwanted dependencies. The test therefore can look like this:

 

        
	[Test]
        public void GetActiveUsers_TestCaseOfZeroUsers()
        {
            IUserManager userManager = 
		mockRepository.DynamicMock<IUserManager>();
            Expect.Call(userManager.NumberOfUsersActiveInLast10Days(null))
                .IgnoreArguments()
                .Return(0);
            mockRepository.ReplayAll();

            DALRepository.CompanyManager.UserManager = userManager;
            IList<int> results = DALRepository.CompanyManager.GetActiveUsers();
            Assert.IsTrue(results.Count == 0);
        }

As we can see in line 12, to set the CompanyManager to use UserManager mock, all we needed to do is to set the UserManager property to the appropriate value.

What's wrong with this?

Well, nothing is especially wrong with this code because we have code open for testing, but encapsulated to the developer using the code. In most cases I consider this an acceptable solution - it is not too complete, and does not rely on any supporting code.

But, in the real world, one class often has multiple dependencies even if it doesn't violate the SoC (Separation of Concerns). To support that with our code, we would have to implement multiple internal properties for the class, implement the lazy load, handle threading issues, etc. That would lead to a lot of code noise which we then have to hide in regions. The same story then repeats in other components, which multiplying the amount of code noise.

Another potential problem is that, to support the poor man's injection, we would have to reference the assembly containing the type. This could lead to the increasing risk of cyclical references (especially if the interfaces are located in a separate assembly).

From OOP purist perspective, setting attributes of "production" assemblies just to support testing needs feels "smelly". Adding a new test assembly would require adding a new attribute to the tested assembly.

Summarized: IMHO, while there are not a a lot of problems with the dependency injection pattern, dependency injection frameworks are a simple solution to these problems.

One thing all DI frameworks have in common

They are all based on the service locator pattern, which replaces the direct dependencies between the types with a dependency to well-known-object which, in turn, is capable of finding and instantiating the appropriate types. The following two diagrams show the essence of this pattern:

image

With tight coupling, class A has to refer directly to an instance of Service A.

With the Service Locator pattern, Class A is asking the Service Locator to "find" Service A "from somewhere" and return an instance to Class A.

Some configuration, a little bit of magic and registration

As we can guess from previous picture, the service locator has to have some way of knowing where to find Service A and Service B. Alternatively, the service location can provide a way for Service A and Service B to register themselves. Usually DI frameworks provide 3 ways for this: a configuration file, attribute decoration or manual registration.

XML configuration files

You can use an XML file to define the dictionary of service contracts and service implementations.

Something like this:

<configuration>
	<configSections>
		<section name="DIFrameworkSection" 
			type="DIFramework.SectionHandler, DIFramework" />
	</configSections>

	<DIFrameworkSection>
		<mappings>
			<mapping key="serviceA.Mapping" 
				type="Component.ServiceA, Component" />
			<mapping key="serviceB.Mapping" 
				interface="Component.IServiceA, Component"  
				type="Component.ServiceA, Component" />
		</mappings>
	</DIFrameworkSection>
</configuration>

As we can see in this example, we are adding a new configuration section into the configuration file. This section defines a list of "mappings" which the service locator uses to instantiate the appropriate service.

Usually, DI  frameworks offer two ways of defining mappings:

    • Mapping Definition 1: key - type definition  (ServiceA)

      where the type contains the name of class and the assembly containing the implementation of that class.

A sample call to the service locator in this case would look like this:

ServiceA service=ServiceLocator.GetInstance<ServiceA>();

    • Mapping Definition 2: key - interface - type definition (ServiceB)

      where we add an interface mapping so the service locator can be called with just the interface information provided. This decouples the service locator from a concrete implementation of the class.

A sample call to the service locator in this case would look like this:

IServiceB service=
	ServiceLocator.GetInstance<IServiceB>("serviceB.Mapping");

Attribute magic

Besides the configuration files, DI frameworks usually offer another way of enabling the service locator to automatically discover the services it should instantiate.

The concept is very simple: all the services are marked with an attribute and the DI framework performs reflexive inspection of the types in the given assemblies and registers these mappings. This happens once per application life cycle, during the DI framework's initialization sequence. No configuration files are needed.

Here's an example of what service locator attribute definition looks like (in pseudo code)

[MappingClassAttribute("serviceA.mapping")]
public class ServiceA
{
    ...
}


[MappingAbstractionAttribute("serviceB.abstraction.mapping")]
public class IServiceB
{
    ...
}


[MappingClassAttribute("serviceB.mapping")]
public class ServiceB: IServiceB
{
    ...
}

As we can see from the example above, we have once again defined the mapping to include a concrete implementation of both ServiceA and ServiceB and an abstract interface for IServiceB.

During the init sequence, there's a call to something like this

ServiceLocator.ScanAssemblies();

This causes the Service Locator to recursively walk through the project assemblies and collect of all the concrete and abstract entities marked with appropriate attributes.

The usage is exactly the same as in case of configuration file:

ServiceA serviceA=ServiceLocator.GetInstance<ServiceA>();

IServiceB serviceB=ServiceLocator.GetInstance<IServiceB>("serviceB.mapping");

Manual registration

During the creation of unit test methods, we usually need to swap a "real" service with the mocked instance containing the values needed for unit test execution. We can do this by having two different configuration files: production and test one. Alternatively, we could just have a production configuration file which includes overrides for test methods that require services.

The DI frameworks factory class exposing static method which can be used to define new service locator mappings (or override existing ones).

        
	[Test]
        public void ServiceA_TestXYZ()
        {
            IServiceA serviceA = mockRepository.DynamicMock<IServiceA>();
            
            /* setup values of mocked service
             * ....*/

            ServiceLocator.RegisterService<IServiceA>(serviceA);
            mockRepository.ReplayAll();

            /* perform unit test */
        }

Notice that, in line 9, we have set up the ServiceLocator to return a mocked instance of the type implementing IService which the tested code would then use inside of the test. This looks similar to the dependency injection solution at the beginning of this post, which is not surprising as we have just replaced a custom implementation of dependency injection design pattern with a pre-built dependency injection framework.

What's next?

After this general introduction to DI frameworks concepts, in next part of this Design for Testability series I will give a "How To" overview of Castle Windsor DI Framework (continuing with the same example I have used thus far). I will also highlight the advantages and disadvantages of Windsor compared to other DI frameworks and show some sample unit tests using Windsor.

So, stay tuned :)

[edited by cbeauvais]

Filed under: Uncategorized No Comments