Post Format

A custom Unity lifetime manager

Leave a Reply

Lifetime management is an important responsibility of a dependency injection container: if the DI container serves the dependencies for you then the DI container should manage the lifetime of the served objects.

The most common lifetime management strategies are transient (new instance per resolve), singleton (one instance per container) and per-request (new instance per web request). Most of the time these are enough but don’t forget the possibilities: you can create any kind of lifetime managers.

What is the task of a lifetime manager in it’s most basic form? Actually it’s very simple. It should decide between two things:

  1. return an existing object or
  2. return nothing

If it returns an existing object then the container will use that. If it returns nothing then the container will create a new instance (based on the configuration) and calls back to the lifetime manager with the created object (so it can do whatever it wants to do with it).

I used this analogy a few weeks ago for a file based component: it loads its information from files and stores it in memory. Actually it builds up itself from files. It can be anything but imagine a file based localization library for example.

Once the actual object graph is ready then we don’t need the files again until they change. It sounds like a singleton lifetime situation and the obvious answer to reload the files should be to watch it in the component implementation. But wait a minute: we already implemented the reloading. It happens when the object graph created by the container. Then why would we implement it again? The container created the object so it should decide when we should receive a freshly built one.

So what we need is the following:

public class FileWatcherSingletonLifetimeManager 
	: ContainerControlledLifetimeManager
{
	private readonly string[] _fileNames;

	private readonly string _cacheKey;

	public FileWatcherSingletonLifetimeManager(
		params string[] fileNames)
	{
		_fileNames = fileNames;
		_cacheKey = CreateCacheKey();
	}

	protected override object SynchronizedGetValue()
	{
		return HttpContext.Current.Cache[_cacheKey] == null 
			? null 
			: base.SynchronizedGetValue();
	}

	protected override void SynchronizedSetValue(object newValue)
	{
		base.SynchronizedSetValue(newValue);
		HttpContext.Current.Cache
			.Insert(_cacheKey, new object(), 
				new CacheDependency(_fileNames));
	}

	private static string CreateCacheKey()
	{
		return "FileWatcherSingletonLifetimeManager:" 
			+ Guid.NewGuid();
	}
}

It builds on the fact that the .NET framework already has the feature to invalidate a cache object if certain files changed. We just pass a simple object to the cache but we aren’t actually interested in the object: we are interested in the existence of the object.

If we turn back to my previous simplification then it does the following:

  1. if we don’t have a flag in the cache then we should return nothing (then the container will create a new instance)
  2. if we have the flag in the cache then we should return the object

The base class of the solution is the ContainerControlledLifetimeManager which is the singleton lifestyle equivalent in Unity. Our class is only a proxy in front of it so what we get is a singleton lifetime managed object which is only singleton until certain file system events: if any of the given files changes then the container will rebuild the object and we restart the cache cycle.

What custom lifetime managers do you use? šŸ™‚

Advertisements

Leave a Reply

Required fields are marked *.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s