Examples: Using Unity to Implement DI

Applies to: Windows Communication Foundation

Published: June 2011

Author: Alex Culp

Referenced Image

This topic contains the following sections.

  • Wrapping Unity
  • Using Unity with a Manager

Wrapping Unity

It is a good idea to wrap Unity (or any other DI provider) with another class, so that you only have to write the logic that loads the Unity container once. The classes that consume the DI will do so through a façade class. The following code is a sample implementation of a DI façade that is based on Unity. It is not complete, and you can enhance it to suit your own projects. There are Microsoft® Visual Studio® C#, and Visual Basic implementations.

Visual C# Implementation of a Unity Façade

/// <summary>
/// Simple wrapper for unity resolution.
/// </summary>
public class DependencyFactory
{
    private static IUnityContainer _container;

    /// <summary>
    /// Public reference to the unity container which will 
    /// allow the ability to register instrances or take 
    /// other actions on the container.
    /// </summary>
    public static IUnityContainer Container
    {
        get
        {
            return _container;
        }
        private set
        {
            _container = value;
        }
    }

    /// <summary>
    /// Static constructor for DependencyFactory which will 
    /// initialize the unity container.
    /// </summary>
    static DependencyFactory()
    {
        var container = new UnityContainer();
            
        var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
        if (section != null)
        {
            section.Configure(container);
        }
        _container = container;
        }

    /// <summary>
    /// Resolves the type parameter T to an instance of the appropriate type.
    /// </summary>
    /// <typeparam name="T">Type of object to return</typeparam>
    public static T Resolve<T>()
    {
        T ret = default(T);
 
        if (Container.IsRegistered(typeof(T)))
        {
            ret = Container.Resolve<T>();
        }
 
        return ret;
    }
}

Visual Basic Implementation of a Unity Façade

''' <summary>
''' Simple wrapper for unity resolution.
''' </summary>
Public Class DependencyFactory
Private Shared _container As IUnityContainer

''' <summary>
''' Public reference to the unity container which will 
''' allow the ability to register instrances or take 
''' other actions on the container.
''' </summary>
Public Shared Property Container() As IUnityContainer
Get
Return _container
End Get
Private Set
_container = value
End Set
End Property

''' <summary>
''' Static constructor for DependencyFactory which will 
''' initialize the unity container.
''' </summary>
Shared Sub New()
Dim container = New UnityContainer()

Dim section = DirectCast(ConfigurationManager.GetSection("unity"), UnityConfigurationSection)
If section IsNot Nothing Then
section.Configure(container)
End If
_container = container
End Sub

''' <summary>
''' Resolves the type parameter T to an instance of the appropriate type.
''' </summary>
''' <typeparam name="T">Type of object to return</typeparam>
Public Shared Function Resolve(Of T)() As T
Dim ret As T = Nothing

If Container.IsRegistered(GetType(T)) Then
ret = Container.Resolve(Of T)()
End If

Return ret
End Function
End Class 

Using Unity with a Manager

The simplest way to begin using DI with WCF is to separate your service into a lightweight implementation that has a pass-through to the actual implementation. You can call the lightweight implementation the service, and the pass-through the manager. The service needs two constructors. One is the default constructor, and the other is a constructor that takes the manager in as a parameter. The default constructor uses the Unity façade to retrieve the dependency to the manager. The following code shows how to do this.

Visual C# Simple Dependency Injection Example

[ServiceContract]
public interface IExampleService
{
    [OperationContract]
    void DoWork();
}
public class ExampleService : IExampleService
{
    private readonly IExampleManager _exampleManager;
 
    public ExampleService():this(DependencyFactory.Resolve<IExampleManager>())
    {
        
    }
 
    public ExampleService(IExampleManager exampleManager)
    {
        _exampleManager = exampleManager;
    }
 
    public void DoWork()
    {
        _exampleManager.DoWork();
    }
}
public interface IExampleManager
{
    void DoWork();
}
public class ExampleManager : IExampleManager
{
    public void DoWork()
    {
        throw new NotImplementedException();
    }
}

Visual Basic Simple Dependency Injection Example

<ServiceContract> _
Public Interface IExampleService
<OperationContract> _
Sub DoWork()
End Interface

Public Class ExampleService
Implements IExampleService
Private ReadOnly _exampleManager As IExampleManager

Public Sub New()

Me.New(DependencyFactory.Resolve(Of IExampleManager)())
End Sub

Public Sub New(exampleManager As IExampleManager)
_exampleManager = exampleManager
End Sub

Public Sub DoWork() Implements IExampleService.DoWork
_exampleManager.DoWork()
End Sub
End Class

Public Interface IExampleManager
Sub DoWork() Implements IExampleService.DoWork
End Interface

Public Class ExampleManager
Implements IExampleManager
Public Sub DoWork() Implements IExampleManager.DoWork
Throw New NotImplementedException()
End Sub
End Class 

You can now test the implementation of the service without a hosting environment such as IIS or Cassini. You can also inject new behaviors between the service and the manager, such as exception management or validation.

Previous article: The Dependency Injection Design Pattern

Continue on to the next article: Using Instance Provider and ServiceHostFactory to Construct the Service