Introducing Unity.WCF - providing easy IoC integration for your WCF services

There are numerous blog posts available that explain how to hook up Unity with WCF. Unfortunately, many of these are incomplete, too basic or just plain wrong. Additionally, as far as I can tell, nobody has created a NuGet package to get you up and running as quickly as possible. This post introduces Unity.WCF, an open source NuGet package that (hopefully) just works in most situations, deals with cleaning up IDisposable instances and also provides a nice mechanism for automatically adding WCF behaviors to your services.

Instantiating a service contract without a parameterless constructor

Out of the box, all service contracts require a default constructor which is obviously somewhat troublesome if you want to inject your dependencies. Making WCF work with IoC is not difficult but it does involve the creation of a few classes in order to hook into the WCF pipeline at the appropriate point. WCF is full of extensibility points and when it comes to service instantiation, the IInstanceProvider interface is what you need.

public interface IInstanceProvider
{
  object GetInstance(InstanceContext instanceContext);
  object GetInstance(InstanceContext instanceContext, Message message);
  void ReleaseInstance(InstanceContext instanceContext, object instance);
}

So, GetInstance needs to create the service instance and ReleaseInstance needs to tidy up afterwards. Virtually all implementations available on the web completely ignore the ReleaseInstance method or just call the TearDown method on the Unity container which looks as though it might do something useful, but in fact does absolutely nothing. The easiest way to dispose of items in Unity on a per client basis is to use child containers. This is exactly how our Unity.Mvc3 library works. Unity.WCF takes a similar approach. The complete UnityInstanceProvider is displayed below:

public class UnityInstanceProvider : IInstanceProvider
{
  private readonly IUnityContainer _container;
  private readonly Type _contractType;
  
  public UnityInstanceProvider(IUnityContainer container, Type contractType)
  {
    if (container == null)
    {
      throw new ArgumentNullException("container");
    }

    if (contractType == null)
    {
      throw new ArgumentNullException("contractType");
    }

    _container = container;
    _contractType = contractType;
  }

  public object GetInstance(InstanceContext instanceContext, Message message)
  {
    var childContainer =
      instanceContext.Extensions.Find<UnityInstanceContextExtension>().GetChildContainer(_container);

    return childContainer.Resolve(_contractType);
  }

  public object GetInstance(InstanceContext instanceContext)
  {
    return GetInstance(instanceContext, null);
  }

  public void ReleaseInstance(InstanceContext instanceContext, object instance)
  {
    instanceContext.Extensions.Find<UnityInstanceContextExtension>().DisposeOfChildContainer();            
  }        
}
	

The code is quite self explanatory. We create a new child container whenever a new connection is made and then use the child container to resolve the service implementation. When the connection is terminated, we dispose of the child container, forcing all IDisposable dependencies to also be disposed (or to be more accurate, all dependencies registered with a HierarchicalLifetimeManager are disposed).

Because a single UnityInstanceProvider is created for the service, we cannot store the child container in a private member variable. Instead, we make use of WCF extensions to store the container on a per client basis. Check out the code on CodePlex if you are interested in this.

Letting WCF know about our custom IInstanceProvider

The next thing we need to do is to get WCF to actually use our instance provider. As is often the case with WCF, this is achieved through behaviors.

public class UnityContractBehavior : IContractBehavior
{
  private readonly IInstanceProvider _instanceProvider;

  public UnityContractBehavior(IInstanceProvider instanceProvider)
  {
    if (instanceProvider == null)
    {
      throw new ArgumentNullException("instanceProvider");
    }

    _instanceProvider = instanceProvider;
  }

  public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
  {
  }

  public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
  {
  }

  public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
  {
    dispatchRuntime.InstanceProvider = _instanceProvider;
    dispatchRuntime.InstanceContextInitializers.Add(new UnityInstanceContextInitializer());
  }

  public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
  {
  }
}

As you can see, the behavior has very little in the way of implementation and most interface methods are empty. All we needs to do is set the InstanceProvider to our injected Implementation in the ApplyDispatchBehavior method. We also add a custom InstanceContextInitializer which is used to hook up the "child container holding" extension that we discussed above. This is not the end of the story however. How do we add the behavior to the service contract (or more accurately, to all the contracts within the service)?

ServiceHost / ServiceHostFactory - the root of a WCF application

The answer is... that it depends. In order to add our behavior and configure our IoC container, we need access to the root of the WCF application - the compositional root. Depending upon how you are hosting your WCF service, this can be seen as either the ServiceHost or the ServiceHostFactory. We will subclass both of these to cover WAS and Windows Service hosted scenarios.

public abstract class UnityServiceHostFactory : ServiceHostFactory
{
  protected abstract void ConfigureContainer(IUnityContainer container);

  protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
  {
    var container = new UnityContainer();

    ConfigureContainer(container);

    return new UnityServiceHost(container, serviceType, baseAddresses);
  }        
}

The UnityServiceHostFactory is declared as an abstract class with an abstract ConfigureContainer method. This allows users of the library to subclass it in their WAS hosted WCF services, implement ConfigureContainer and add their Unity registration code. It effectively exposes an entry point into the service which is otherwise unavailable. Internally, we instantiate a new UnityServiceHost, passing in the configured container.

public class UnityServiceHost : ServiceHost
{
  public UnityServiceHost(IUnityContainer container, Type serviceType, params Uri[] baseAddresses)
    : base(serviceType, baseAddresses)
  {
    if (container == null)
    {
      throw new ArgumentNullException("container");
    }

    ApplyServiceBehaviors(container);

    ApplyContractBehaviors(container);

    foreach (var contractDescription in ImplementedContracts.Values)
    {
      var contractBehavior =
        new UnityContractBehavior(new UnityInstanceProvider(container, contractDescription.ContractType));

      contractDescription.Behaviors.Add(contractBehavior);
    }
  }

  private void ApplyContractBehaviors(IUnityContainer container)
  {
    var registeredContractBehaviors = container.ResolveAll<IContractBehavior>();

    foreach (var contractBehavior in registeredContractBehaviors)
    {
      foreach (var contractDescription in ImplementedContracts.Values)
      {
        contractDescription.Behaviors.Add(contractBehavior);
      }                
    }
  }

  private void ApplyServiceBehaviors(IUnityContainer container)
  {
    var registeredServiceBehaviors = container.ResolveAll<IServiceBehavior>();

    foreach (var serviceBehavior in registeredServiceBehaviors)
    {
      Description.Behaviors.Add(serviceBehavior);
    }
  }
}
	

The UnityServiceHost loops around all contracts within the service and adds our custom behavior to each. The ApplyServiceBehaviors and ApplyContractBehaviors add the ability to register behaviors with Unity and have them automatically be applied by the ServiceHost.

Automatic Behaviors

Any implementations of IServiceBehavior or IContractBehavior that are registered with Unity will automatically be applied by the custom ServiceHost. Why is this useful? You can already apply behaviors though configuration and attributes but these methods do not allow you to inject dependencies into your behaviors. With Unity.WCF, this is trivial.

container
  .RegisterType<IContractBehavior, ErrorBehavior>("errorHandlerBehavior")
  .RegisterType<IErrorLogger, AnErrorLogger>();

In the above example, the ErrorBehavior class has a constructor that takes in an IErrorLogger. Since an implementation of this interface is also registered with Unity, the ServiceHost will be able to instantiate the ErrorBehavior and add it to the service automatically.

The only thing to be aware of is that these behavior registration must be named. This is because internally, we use container.ResolveAll<...> which only returns named instances.

container
  .RegisterType<IServiceBehavior, ValidateDataAnnotationsBehavior>("validationBehavior")
  .RegisterType<IServiceBehavior, SomeOtherBehavior>();

In the example registration displayed above, only the ValidateDataAnnotationsBehavior will be added. SomeOtherBehavior is not named so will be ignored. Note that the registration name itself is not important. Just having ANY name is sufficient.

Adding Unity.WCF to your project

Using the Package Manager Console, type install-package Unity.WCF.

Alternatively, you can use the Package Manager GUI and search for Unity.WCF. The Unity.WCF NuGet package will automatically add all the necessary references including the Unity NuGet package. Once installed, your next action depends on how you are hosting your service.

WAS / IIS hosted services

For IIS/WAS-based hosting, right click on your svc file in the solution explorer and select View Markup. Next replace CodeBehind="Service1.svc.cs" with Factory="WcfService1.WcfServiceFactory", where WcfService1 is the namespace of your project. If you are using fileless activation and do not have an SVC file, change your web.config instead.

<serviceHostingEnvironment>
  <serviceActivations>
    <add factory="WcfService1.WcfServiceFactory" relativeAddress="./Service1.svc" service="WcfService1.Service1"/>
  </serviceActivations>
</serviceHostingEnvironment>

Open the WcfServiceFactory class that has been added to the root of your application. Add all necessary component registrations. If you are registering IDisposable components that need to be created and destroyed on a per client basis (i.e. an EntityFramework DataContext), please ensure that you use the HierarchicalLifetimeManager:

container
  .RegisterType<IService1, Service1>()
  .RegisterType<IRespository<Blah>, BlahRepository>()
  .RegisterType<IBlahContext, BlahContext>(new HierarchicalLifetimeManager());

Windows Service hosting

If you are hosting your WCF service within a Windows Service using a ServiceHost, replace the ServiceHost instance with the custom Unity.Wcf.UnityServiceHost. You will find that the UnityServiceHost takes in a Unity container as its first parameter but is otherwise identical to the default ServiceHost.

Delete the WcfServiceFactory class that has been added to the root of your application. It is not necessary for non-WAS hosting. Instead, you are free to configure Unity any way you like as long as the configured container is passed into the UnityServiceHost correctly. As with WAS hosting, if you want Unity.WCF to dispose of IDisposable components, you must register those components using the HierarchicalLifetimeManager lifestyle.

My IDisposable Instances are not being disposed

If you add the Unity.WCF NuGet package to your application and get everything up and running and your disposable object are still not being disposed...then you are probably doing something wrong. The most likely causes are:

(1) You did not register your disposable type correctly with Unity. Remember than you must specify the HierarchicalLifetimeManager.

(2) Your client is not closing the connection to your service and you are using InstanceContextMode.PerSession (the default). Make sure that your client always closes the channel once it has finished calling it. Also consider changing the context mode to PerCall to remove this client responsibility and also make your service far more scalable.

Conclusion

Unity.WCF is a small library that allows simple integration of the Unity IoC container into WCF projects. Unlike many online examples, Unity.WCF will automatically dispose of configured IDisposable instances at the end of each request making it particularly useful when using ORM's such as Entity Framework. Unity.WCF is now available as a NuGet package and as a full source download on CodePlex.

Useful or Interesting?

If you liked the article, I would really appreciate it if you could share it with your Twitter followers.

Share on Twitter

Comments

Avatar for Westerne Westerne wrote on 20 Jan 2012

That's very good article, how to use this with IIS activation

Avatar for Paul Hiles Paul Hiles wrote on 20 Jan 2012

@Westerne - when I mention WAS (Windows Process Activation Service), I really mean any IIS hosted service. I have updated the article to make this clearer.

If you follow the instructions above (under the heading 'WAS / IIS hosted services'), you should be able to get up and running in a couple of minutes.

After you download the NuGet package, there are really only two steps:

(1) add your Unity configuration to the autogenerated WcfServiceFactory class.
(2) edit your svc file to use the custom WcfServiceFactory factory.

Avatar for Tim B Tim B wrote on 26 Jan 2012

I wish I had found this a few days ago, before I starting wading through all those incomplete blog posts trying to figure this out myself. Stumbled across this when I was trying to figure out how to dispose of my Unity container. Thanks for the help.

Avatar for David D David D wrote on 10 Feb 2012

I must be missing something here...
I followed your instructions to add the Package to my project.

I registered my Interface in the WCFServiceFactory.cs

Now, How do I resolve this type inside my WPF app? I can't seem to get the Unity container to find the interface type right it seems.

Assume my Interface is IBPService and Class is BPService

Assume my Service namespace is BPService

How would this be done in my WPF app?
preferrably through a unity configuration section


Thanks!

Avatar for Paul Hiles Paul Hiles wrote on 10 Feb 2012

@David - Unity.WCF allows you to do dependency injection in a WCF service using the Unity IoC container. Think of your WCF service as something that is totally separate from any client application. A WCF service is an application in its own right. Unity.WCF allows your host (typically either a windows service or IIS / WAS) to instantiate your service and satisfy any dependencies.

I think what you are talking about is calling the service from a client (the WPF application) which is a different concern and nothing to do with Unity.WCF. Typically you would add a service reference or generate a proxy using svcutil.exe but there are some nicer ways which we will talk about in future blog posts.

Just in case you are actually talking about hosting your WCF service within the WPF application, you can follow the windows service instructions and use the custom UnityServiceHost in place of the built-in ServiceHost that you would normally use.

Avatar for David D David D wrote on 13 Feb 2012

Yes I understand the Service side. I was talking about how to pull this type out of the container on the client side using Unity. Can consume the WCF service but I was trying to use Unity on the client side to Resolve<> the types.

Avatar for David D David D wrote on 14 Feb 2012

Maybe I misunderstand the use of the unity container in the WCF Server side.

Is it not to allow the container to be passed along to the client for resolving the reference?

Avatar for Paul Hiles Paul Hiles wrote on 14 Feb 2012

@David - The client and the service are completely separate applications and whilst you can use Unity in both, they are separate instances of Unity with completely different configuration. There is no (and should never be any) sharing of the container between service and client.

At the service side, you use Unity to inject dependencies into your service implementation. This is the purpose of Unity.WCF.

On the client side, you can use Unity to resolve your proxy. If you are not generating a service proxy and are sharing your contracts and using some sort of ChannelFactory implementation to dynamically create a proxy, you can also use Unity here. The client-side code is outside the scope of this article though and not related to the Unity.WCF NuGet package.

In the next few weeks, I will be releasing a package that will greatly simplify the process of referencing and calling internal WCF services.

Avatar for Fredrik Fredrik wrote on 07 Mar 2012

I use AppFabric Auto-Start with
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] on the service,

and with a default constructor, the constructor is called as soon as the web application is started (no need for calling it), and my code is executed as I want it to do.
public DataManagementService()
{
this.Start();
}

But when adding unity and the container to the service this approch stops working, no more default constructor, so my code is not executed on startup anymore.

My service constructor now looks like this

public DataManagementService(IUnityContainer container)
{
this.container = container;
this.Start();
}

Is there any way to execute some code an startup like the attribute
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] provides?

Avatar for Paul Hiles Paul Hiles wrote on 08 Mar 2012

@Fredrik - Using InstanceContextMode.Single makes your service scale very badly so is best avoided in most cases, particularly if it is just being used to allow AppFabric auto-start. You can safely remove the ServiceBehavior attribute and do it another way.

With Unity.WCF, you can add your initialisation code to the ConfigureContainer method of the WcfServiceFactory class that is created when you add the Unity.WCF NuGet package. This will only be executed once for the lifetime of the service.

BTW, you should not be passing the Unity container into your service. Add any components that your service uses into the constructor (e.g. repositories, helpers etc.) and also register then with Unity using the ConfigureContainer method. When your service is instantiated, the dependencies will be injected automatically.

Avatar for Fedrik Fedrik wrote on 08 Mar 2012

Thx for getting back :-)

I have change that now, so now it passes in my logger instead.

The Start() method I'm executing holds a FileSystemWatcher, that is what the service is all about, the service looks at new file events, and when a new file is created it takes that file and passes it to a workflow, that is created for each file. The only client part here, is to ask the service if all is up and running and whiteout any errors. So the service mainly works as a windows service, but I need it to run in IIS/WAS.

When the web applciation starts up the service must start watching folders automatically without starting up a client and make a call to it.

So how can I make the service execute my Start() method automatically (e.g. if the applicationpool is recycled)?

This is how it looks now.
protected override void ConfigureContainer(IUnityContainer container)
{
// Register all your components with the container here.
container
.RegisterType<IDataManagementService, DataManagementService>(new ContainerControlledLifetimeManager())
.RegisterType<ILogger, Logger>(new ContainerControlledLifetimeManager(), new InjectionConstructor(@"C:\Test\"));
}

Avatar for Peter Oscarsson Peter Oscarsson wrote on 23 Mar 2012

Thank you very much for this code. It fits nicely into our application framework for LOB applications.

/P

Avatar for Johan Johan wrote on 09 Apr 2012

Great article!

I would have preferred if the source code was available and not only a dll thou with reflector I peaked a little in it to see it all :-)

Avatar for Paul Hiles Paul Hiles wrote on 10 Apr 2012

@Johan - You can view and download the source code on CodePlex. Just select the Source Code tab at the top and select the change set you require :-)

http://unitywcf.codeplex.com/SourceControl/list/changesets

Avatar for jack jack wrote on 11 Apr 2012

probably a dumb question being new to unity... after all is set up how do I obtain the reference back within the service e.g. call container.Resolve<T>?
Thanks

Avatar for Paul Hiles Paul Hiles wrote on 11 Apr 2012

@jack - you shouldn't need a reference to your container within the service. Add any components that your service requires to the service constructor and they will automatically be injected when your service is instantiated.

See the article below for more information:

http://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton-container

Avatar for jack jack wrote on 11 Apr 2012

thank, yes I understand ctor injection.. in this case though it won't work because there is a number of static classes that use other services and components which needed to be resolved based on configuration. So I guess so-called "service locator" in this case suits better and seemed work fine so far. Actually I don't completely agree that service locator is an anti-pattern..

Avatar for jack jack wrote on 18 Apr 2012

Thanks, works like a charm! one thing i wanted to mention though.. in case InstanceContextMode is Single, ServiceHostFactory doesn't get called..

Avatar for Jason Jason wrote on 25 Apr 2012

Awesome, thanks for doing this. To make it a complete solution your assembly should be signed. Otherwise we have to download your code and sign it our selves, then deploy it internally which defeats the purpose of NuGet. Have you considered signing the assembly?

Avatar for Paul Hiles Paul Hiles wrote on 26 Apr 2012

@Jason - there is a lot of debate about whether to sign assemblies in NuGet. Take a look at the post below.

http://nuget.codeplex.com/discussions/247827

Avatar for Daniel Schlößer Daniel Schlößer wrote on 04 May 2012

Thanks for your nice solution.
I have a question though: My WCF services are in a dll so that I can easily share the service interface definitions. How would I configure the ServiceHost when I debug the services and they run inside the Visual Studio WCF test host? Would it work like in the IIS/WAS case that I have to configure it in the app.config?

Avatar for Vilsad Vilsad wrote on 10 Aug 2012

Hi,
I have implemented unity.wcf for my wcf layer, but i need to carry forward a log component object all the way down to my business layer classes using DI. for this i need to get the same instance of the UnityContainer used in wcf layer in my business layer, is there any way to get it ?

Avatar for Jimbo Jimbo wrote on 17 Sep 2012

I'm trying to get this working using WCF serivices hosted in an Azure WebRole.

Is there any additional configuration required? I'm using the settings you recommended for WAS but it looks like the service is not being activated.

Avatar for Jaydeep Jaydeep wrote on 03 Oct 2012

Thanks for this article. This helped me a lot while development.

I have create a WCF Service which has parameterised constructor. According to the parameter values i get the specific dll and creates an object of a specific class. Then the whole service runs using that object. I have use the Unity.Wcf dll in my WCF Service through which i am able to start this service and get connected to it. I have also provided object and type reference information in the configuration file.

But my Question is how to provide parameter values at the time of wcf service object creation at the asp application (i.e. client side). Is this possible? When i try to create an object for wcf service i don't get the constructor parameters.

Avatar for Koray Asili Koray Asili wrote on 10 Oct 2012

Hi, thanks for article, what i want to do is simply using my container inside service method(operation contract) to be able to get repository instance from container. How can i get container instance ?

public string ServiceMethod(){
IRepository repository = container.Resolve...
return repository.SayHi();
}

Avatar for brix brix wrote on 14 Nov 2012

Hi,
Very very interesting.I would have to say that I am one of those who struggled with many examples on the website.

Now you have done a very good job however it would be great if you had a simple end to end example.
EG a Console app with a self host and one with a windowService etc.. that would make it perfect.

That would also avoid people asking you how to use it

I am sure you must have tested it.Do you have some tests I can download?
Or little app?

Thanks for this anyway
Brix

Avatar for Rohit Rohit wrote on 16 Nov 2012

Hi Paul,

I am using Unity.WCF, and able to configure and use the same. Issue which I want to resolve here is with ThreadLifeTimeManager which is best explained http://blogs.msdn.com/b/atoakley/archive/2010/12/29/unity-lifetime-managers-and-wcf.aspx

Could you please let me know if Unity.WCF package has InstanceContextLifeTimeManage? if not then how can i plug in one from the link I have provied?

Thanks
Rohit

Avatar for Rob Rob wrote on 20 Nov 2012

Nice article and code. I also found the follow up comments to be useful.

You mention: "Typically you would add a service reference or generate a proxy using svcutil.exe but there are some nicer ways which we will talk about in future blog posts."

Had any time recently to show these "nicer ways"?

Avatar for Stu Stu wrote on 06 Feb 2013

Great article!

How would one go about using Unity.WCF with System.Data.Services.DataService<T> ?

The DataService<T> utilizes System.Data.Services.DataServiceHostFactory rather than ServiceHostFactory. But DataServiceHostFactory does directly inherit ServiceHostFactory.

Avatar for Paul Hiles Paul Hiles wrote on 06 Feb 2013

@Stu - The main release of Unity.Wcf does not support WCF data services. Sergey Prokofiev has created a fork that you can use though:

http://unitywcf.codeplex.com/SourceControl/network/forks/SergeyProkofiev/UnityDataServices

I will look at integrating the changes into master at some point but we are super busy right now and do not have sufficient knowledge in this area to ensure that it is 100% - we tend to use Web API.

I would certainly appreciate your feedback if you do give it a go.

Avatar for Sunny Sunny wrote on 22 Feb 2013

Hi,

What is the impact of setting InstanceContextmode as Single and Multiple concurrancy with Unity Container. will it be thread safe?

Avatar for Nail Salikhov Nail Salikhov wrote on 26 May 2013

Why UnityServiceHostFactory always create new instance of UnityContainer? I think it should create container and configure it only once.