Resolving Instances using Delegates in Unity


In previous posts, I have covered bootstrapping Unity in MVC, using Unity as a DependencyResolver in MVC and using Unity in conjunction with WCF services. I am going to extend the Unity theme a little bit more and describe a technique I use to get Unity to return a instance of a WCF Channel for a requested service interface.

One of things I like about StructureMap as an IOC container is ability to use a delegate to provide the required instance for a type, as in the following code.

ChannelFactory<IAccountService> accountChannelFactory = 
                                    new ChannelFactory<IAccountService>("AccountService");

ObjectFactory.Initialize(cfg =>
                               => accountChannelFactory.CreateChannel());

Unity has no such method. When specifying an instance to return for a requested type, Unity requires a created instance to use and manages the lifetime of the object as a singleton. This means that the above functionality, where a Channel is created by a delegate to the ChannelFactory to satisfy the resolution of the IAccountService, cannot be readily implemented in Unity.

To get around this limitation, I have designed a LifetimeManager that takes as a parameter a delegate. The implementation, shown below, is simple. In the override for GetValue() the delegate is called.

public class NewInstanceLifetimeManager : LifetimeManager{
   private LifetimeManager baseManager;
   private Func<object> sourceFunc = null;

   public NewInstanceLifetimeManager(Func<object> sourceFunc, 
                                                   LifetimeManager baseManager = null){

     Contract.Requires(sourceFunc != null, "sourceFunc must be provided");
     this.sourceFunc = sourceFunc;
     this.baseManager = baseManager;

   public override object GetValue(){
     object result = baseManager.GetValue();

     if (result == null){
       result = sourceFunc();

       if (baseManager != null){

     return result;

  public override void RemoveValue(){
    if (baseManager != null){

  public override void SetValue(object newValue){
    if (baseManager != null){

This seems to work pretty well as in the following:

ChannelFactory<IAccountService> accountChannelFactory = 
                                   new ChannelFactory<IAccountService>("AccountService");

               new NewInstanceLifetimeManager(()=>accountService.CreateChannel()));

Note how the NewInstanceLifetimeManager takes an underlying LifetimeManager implementation as an optional paramater. For channels I like to use a per-request context lifetime manager. I can use the NewInstanceLifetimeManager in conjunction with the ContextLifetimeManager as follows (I am using the container to resolve the ContextLifetimeManager so that the required ContextItemProvider constructor parameter is set):

ChannelFactory<IAccountService> accountChannelFactory = 
                      new ChannelFactory<IAccountService>("AccountService");

  new NewInstanceLifetimeManager(() => businessService.CreateChannel(), 
                                 container.Resolve<ContextLifetimeManager>() ));


This post has covered how to extend the functionality of the Unity IOC container to enable the getting of instances using a delegate through the use of a LifetimeManager that takes a delegate as a parameter. A useful application of this technique is for the creation of WCF Channels from channel factories.

kick it on

About these ads
This entry was posted in StructureMap, Unity and tagged , , . Bookmark the permalink.

One Response to Resolving Instances using Delegates in Unity

  1. Good post. One correction: we’ve added to Unity 2.0 a capability to use a delegate to provide the required instance for a type. It’s called InjectionFactory.

Leave a Reply

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

You are commenting using your 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