SourceForge.net Logo

Home
StructureMap on SourceForge
Basic Architecture
Concepts
API Documentation
FAQ
Configuration Schema
    Memento Sources
    Node Normalized Xml
    Attribute Normalized Xml
    Attribute Usage
    Instance Lifecyle Scoping
Configuration Management
    StructureMapDoctor
    StructureMapExplorer
    deployment Task
    verification Task
    ValidationMethod Attribute
    Other NAnt Tasks
Troubleshooting
Singleton Injection

Injected Singleton

StructureMap now provides an optional mechanism to create and return a single instance per instance configuration as an alternative to the Singleton pattern I am calling an "Injected Singleton."  A PluginFamily can now be configured to create only one instance for each named instance. 

Singleton Design Pattern

Ensure a class only has one instance, and provide a global point of access to it.

The Singleton pattern from the "Gang of Four" book is undeniably an essential part of any developer's toolbox.  The motivation for using a Singleton is to insure that only one instance of a class is created within the application.   Mechanically, this is accomplished by making a public class with only private constructors.  The class will create and store one instance in a static field.  Other classes can attain a reference to the single instance by calling a static method on the singleton class.  Below is an example Singleton.

public class SingletonExample
{
	private static SingletonExample _instance = new SingletonExample();

	public static SingletonExample Instance
	{
		get
		{
			return _instance;	
		}
	}


	private int _count;

	private SingletonExample()
	{
	}

	public void Increment()
	{
		_count++;
	}

	public int Count
	{
		get { return _count; }
	}
}

public class Transactor
{
	public Transactor(){}

	public void DoSomething()
	{
		SingletonExample.Instance.Increment();
		/*  Do stuff */
	}
}
					

Usages

While the Singleton pattern is probably overused, here are some scenarios where a Singleton or equivalent is valuable.

  1. Caching or object pooling. A Singleton is one of the simplest mechanisms to create a caching mechanism inside your application. 
  2. Easy access to an object instance.  In .NET applications security identity and security permissions are usually stored in an IPrincipal/IIdentity object pair attached to an AppDomain and/or the executing Thread.  By making the IPrincipal a member of the Thread object, the IPrincipal can be accessed from any object without explicitly passing around a reference to the IPrincipal.  The ObjectFactory class in StructureMap is essentially a Singleton-like instance for quick reference to StructureMap services without the overhead of creating and passing a container object between classes.
  3. Using a Singleton as a single point of object construction to control a plugin.  For example, in a Smart Client WinForms application, this creates the ability to switch an application from a connected mode to a disconnected mode to a stubbed mode.  StructureMap's ObjectFactory fulfils this role.

Unit Testing with a Singleton

The primary downfall of a Singleton is a negative impact on automated unit testing.  Test Driven Development with automated unit tests is most effective when unit tests are small, isolated, and running with known boundary conditions.  Since a Singleton class is responsible for creating its single instance, a Singleton may often be in some sort of "dirty" state during later unit test runs.  The unit test is no longer contained within known boundary conditions.  The unit test might give false results.  This problem can be overcome by providing some sort of "Reset()" method on the Singleton to clear the state prior to running a unit test.

The worst, most tightly coupled unit tests I have ever written, mocked the underlying dependencies of a Singleton class to measure the interaction of an MVC controller class with a Singleton repository.  The test class for the controller was tightly coupled to the internal workings of the repository class.  In this case it would be vastly more effective and understandable to mock the repository instead.  This was not possible because the repository class was only accessable as a Singleton instance.Since the only way to get an object instance of the repository was to call the class itself, there was no easy way to substitute a Mock object in a unit test to establish a known boundary condition.

This problem can be eliminated by making all dependencies be on an abstracted interface and using Dependency Injection to attach the shared instance instead of referencing the Singleton directly.

For more information, try here:  Singletons are Evil.

Singleton with StructureMap

StructureMap can be configured to create a shared instance to accomplish the same goals as a Singleton, while still allowing for polymorphic substitutions of the dependency.  The following example shows the usage of Injected Singleton in StructureMap with a modification of the previous code sample.

	[PluginFamily("Concrete", IsSingleton = true)]
	public interface ISingleton
	{
		void Increment();
		int Count {get;}
	}

	[Pluggable("Concrete")]
	public class ConcreteSingleton : ISingleton
	{
		private int _count = 0;		

		public void Increment()
		{
			_count++;
		}

		public int Count
		{
			get { return _count; }
		}
	}

	public class Transactor
	{
		public Transactor(){}

		public void DoSomething()
		{
			ISingleton singleton = (ISingleton) ObjectFactory.GetInstance(typeof(ISingleton));
			/*  Do stuff */
		}
	}

						

A few points about the code sample:

  1. I extracted an interface for the Singleton class
  2. The ISingleton interface is marked with the [PluginFamily] attribute with the optional property IsSingleton set to true.  This directs StructureMap to intercept requests for any ISingleton instance and return the single shared instance.
  3. The Transactor class retrieves an ISingleton from ObjectFactory just like any other plugin type controlled by StructureMap.

An NUnit tester class like the following can now use the Mock Injection feature of StructureMap to substitute a mocked ISingleton inside of a unit test. 

[TestFixture]
public class TransactorTester
{
	IMock _singletonMock;

	[SetUp]
	public void SetUp()
	{
		_singletonMock = ObjectFactory.Mock(typeof(ISingleton));
	}

	[TearDown]
	public void TearDown()
	{
		ObjectFactory.ResetDefaults();
	}

	[Test]
	public void Test1()
	{
		_singletonMock.ExpectCall("DoSomething");
		
		Transactor transactor = new Transactor();
		transactor.DoSomething();
	
		_singletonMock.Verify();
	}
}

						

A PluginFamily can also be explicitly configured to be an Injected Singleton in the StructureMap.config file like the following xml.  The <Interceptors> node instructs StructureMap to make the PluginFamily an injected singleton. 

<PluginFamily Type="StructureMap.Testing.Widget.Rule" Assembly="StructureMap.Testing.Widget" DefaultKey="Blue">

      <Interceptors>

            <Interceptor Type="Singleton"></Interceptor>

      </Interceptors>

     

</PluginFamily>