Integrating Unity Application Block with WCF - Part 1
The Unity Application Block is a lightweight, extensible dependency injection container with support for constructor, property and method call injection. In Layered Architecture, Unity can help us to achieve decoupled or very loosely coupled design between the different tiers (more details about the layered architecture with Unity in the next posts.. ).
There are three ways we can set up and prepare a Unity container by populating it with registered mappings. We can:
- Provide an XML format configuration file that adheres to Unity schema.
- Use the container API to add specific registration entries.
- Use the container configuration API to provide custom configuration for the container.
The steps below demonstrate one way of setting up Unity container within IIS using the web.config technique [most credits go to Jorg Joose) . The steps are:
- Create WCF Extension class to hold the Unity container.
- Create WCF ServiceHost class and override the InitializeRuntime method to set up the Unity container.
- Create WCF ServiceHostFactory class to initialize the custom WCF ServiceHost.
- Update the .svc file to load the custom ServiceHostFactory class.
- Update WCF web.config to contains the Unity mappings.
Create WCF Extension Class
class UnityExtension : IExtension<ServiceHostBase>, IDisposable
{
private static readonly object containerLock = new object();
private static IUnityContainer containerSingleton;
internal UnityExtension(IUnityContainer container)
{
lock (containerLock)
{
if (containerSingleton == null)
{
containerSingleton = container;
}
}
}
internal IUnityContainer Container
{
get { return containerSingleton; }
}
#region IExtension<ServiceHostBase> Members
public void Attach(ServiceHostBase owner)
{
// Not used.
}
public void Detach(ServiceHostBase owner)
{
// Not used.
}
#endregion
#region IDisposable Members
public void Dispose()
{
lock (containerLock)
{
if (containerSingleton == null)
{
containerSingleton.Dispose();
containerSingleton = null;
}
}
}
Create WCF ServiceHost Class
public class UnityServiceHost : ServiceHost
{
public UnityServiceHost(Type serviceType, Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
}
public UnityServiceHost(object singletonInstance, Uri[] baseAddresses)
: base(singletonInstance, baseAddresses)
{
}
protected override void InitializeRuntime(){
VirtualPathExtension extension = Extensions.Find<VirtualPathExtension>();
Configuration config = WebConfigurationManager.OpenWebConfiguration
(extension.VirtualPath);
IUnityContainer container = new UnityContainer();
UnityConfigurationSection section = (UnityConfigurationSection)config.GetSection("unity");
section.Containers.Default.Configure(container);
Extensions.Add(new UnityExtension(container));
base.InitializeRuntime();
}
}
Create WCF ServiceHostFactory Class
public class UnityServiceHostFactory : ServiceHostFactory{
protected override ServiceHost CreateServiceHost
(Type serviceType, Uri[] baseAddresses){
return new UnityServiceHost(serviceType, baseAddresses);
}
}
Update svc file
The svc file should declare the custom ServiceHostFactory class
<%@ ServiceHost Language="C#" Debug="true" Factory="UnityServiceHostFactory"%>
Update WCF web.config
For example (mapping between ICustomerOrchestration interface type to CustomerOrchestrationImplementation concrete type)
<unity>
<typeAliases>
<!-- Lifetime manager types -->
<typeAlias alias="singleton"
type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,
Microsoft.Practices.Unity" />
<typeAlias alias="external"
type="Microsoft.Practices.Unity.ExternallyControlledLifetimeManager,
Microsoft.Practices.Unity" />
<!-- User-defined type aliases -->
<typeAlias alias="ICustomersOrchestration"
type="CustomerOrchestrationInterface" />
</typeAliases>
<containers>
<container>
<types>
<type type="ICustomerOrchestration"
mapTo="CustomersOrchestrationImplementation">
</type>
</types>
</container>
</containers>
</unity>Stay tune for the next posts.