WCF

WCF + IoC = Unity.WCF

Keep service contracts clean
In my last post on implementing IErrorHandler for WCF, it was reasonably straight forwards to write a class that implements IErrorHandler; however to attach our errorhandler to the WCF service we had to apply it as an attribute of the contract.
I generally like to have the service contract in a seperate project from the actual service and have that contract service focus on just the contract. Adding an ErrorHandler attribute in there smells. Below is an alternative way of achieving this.

Make it clean
Ideally we should be attaching the errorhandler at the service level. Be great if we could just use an IoC mechanism to just inject our ErrorHandler into our service. Fortunately, we can!  The downside is that it’s a bit of a pain to code as you need to implement IInstanceProvider, add that through a custom behaviour and fiddle with the servcehost factory, which is a lot of work compared to just adding an attribute to our interface.

Don’t reinvent the wheel
Fortunately someone has done all this work for us and shared it on Nuget. It’s called Unity.WCF. It solves our problem perfectly for us. For a more detailed description of what it does visit http://www.devtrends.co.uk/blog/introducing-unity.wcf-providing-easy-ioc-integration-for-your-wcf-services. Aside from exposing a unity container for you it also allows you to supply implementations of IContractBehavior and IServiceBehavior, which is very hand as we’ll see.

What does it look like?

First install the package from Nuget, either through Visual studio or via this link. This will add a few files to your solution. The key file here is the WcfServiceFactory. If you have a look in here you will see just the one method

 protected override void ConfigureContainer(IUnityContainer container) 

. This method expose a unity container, allowing you to configure this container to inject classes as you want. Out of the box this looks like this

 protected override void ConfigureContainer(IUnityContainer container)
        {
			// register all your components with the container here
            // container
            //    .RegisterType<IService1, Service1>()
            //    .RegisterType(new HierarchicalLifetimeManager());
        }

In order to get our service to use this factory we simply need edit the markup in the .svc file – replace the codebehind call with a factory call.

Out of the box svc markup file:

<%@ ServiceHost Language="C#" Service="WcfService1.Service1" CodeBehind="Service1.svc.cs" %>

Change to:

<%@ ServiceHost Language="C#" Service="WcfService1.Service1" Factory="WcfService1.WcfServiceFactory" %>

Add our ErrorHandler

As we don’t want to apply our Errorhandler code as an attribute to the service contract, lets remove that, so our errorhandler now looks like:

public class ErrorHandler : IErrorHandler, IContractBehavior
{
... same code as before
}

Now we update the container in WcfFactory, to get it to inject our instance of an IContractBehaviour, and also setup the Service. This leaves our container looking like:

 protected override void ConfigureContainer(IUnityContainer container)
        {
        	container
        		.RegisterType<IService1, Service1>()
        		.RegisterType("MyErrorHandler");
        }

We need to give it a name, as unity.wcf uses container.ResolveAll which only returns named instances.

Use Unity to inject log4net

Finally we can tidy up our ErrorHandler from the last post by removing our “poor man’s dependency injection” and replace it with the slicker Unity container.
Previously our constructor looked like:

 public ErrorHandler()
            :this(LogManager.GetLogger("myassembly"))
        {}

        public MyErrorHandler(ILog logger)
        {
            _logger = logger;
        }

Enabling us to fully test the class by injecting an instance of ILog, or, the class would work without by firing up it’s own hard wired instance of log4net.

Now that we have a unity container we don’t need to have the case where the class isn’t injected as unity can manage this for us. So we just need the one constructor now

        public MyErrorHandler(ILog logger)
        {
            _logger = logger;
        }

Finally we update the container to look like

 protected override void ConfigureContainer(IUnityContainer container)
        {
        	container
        		.RegisterType()
        		.RegisterType("MyErrorHandler")
        		.RegisterInstance(LogManager.GetLogger("MyLogger"));
        }

Summary
That’s it. By adding unity.wcf to our WCF service we have, with minimal effort, enabled our WCF to use unity to wire up instances of our service contract, errorhandler and the errorHandler’s dependency on Ilog.

Catch All WCF Errors

Want to log all uncaught errors in a WCF service? Want to return a nicely formatted fault exception too?

IErrorHandler can help.

I like using this interface as you can apply it to an entire WCF Service with just a few lines of code, making it easy to use against numerous WCF services ensuring that your error handling is reliable. It allows you to log your errors in a consistent manner and also do any bespoke cleaning up of resources that you might want to do. On top of this, your implementation of the ErrorHandler can (and should) exist totally outside of your WCF service, allowing a good separation of concerns

This interface exposes two methods:

1. provide fault: This is where you can provide what fault gets sent to the client. By default, sometimes the error gets wrapped up in a fault exception and sent to the client. Sometimes not. Here is where you can wrap up the exception any way you like and return it to the client in a fault exception.

2. handle error: This is where you prove code to handle the error and commonly where you will log the error, raise system alerts, etc.

For MSDN’s description, see here

Let’s Create our class

public class MyErrorHandler : IErrorHandler
{
		private readonly ILog _logger;

		public ErrorHandler()
			:this(LogManager.GetLogger("myassembly"))
		{}

		public MyErrorHandler(ILog logger)
		{
			_logger = logger;
		}
}

Nothing too exciting here – we’re injecting a logging object, or creating one if not provided. We need to implement that interface though.

Let’s provide a fault.

public void ProvideFault(Exception ex, MessageVersion version, ref Message fault)
{
	if (ex is FaultException)
	{
		return;	//WCF will handle this
	}

	var messageFault = MessageFault.CreateFault(new FaultCode("Service"), new FaultReason(ex.Message), ex, new NetDataContractSerializer());
	fault = Message.CreateMessage(version, messageFault, null);
}

In this example I want to make sure that the client receives the error in the fault every time. If the exception is already of type FaultException, then nothing need be done.
So here we are creating a new Message, which contains the exception message. If we didn’t want the client to know the specifics of the fault we could just create a generic message here instead of the exception message.

Let’s handle that error

public bool HandleError(Exception ex)
{
	_logger.Error(ex.Message, ex);

	if (ex is FaultException)
	{
		return false;	//WCF will handle this
	}

	return true;
}

The first line logs the error. Then as you probably noticed this method needs to return a bool. This is so that the dispatcher knows if the error was handled or not. You want to return false in the event the error is a FaultException, as WCF will automatically handle this. Otherwise we need to tell it that we’ve handled it (true).

Wiring it into the WCF service

There are a few ways to achieve this. My preferred method is to take the least painful way and make our ErrorHandler class implement IContractBehaviour and apply it as an attribute to the service’s DataContract. Taking a step back what we need to do is add our ErrorHandler class to the collection of ChannelDispatchers.ErrorHandlers, so our WCF service will use our custom ErrorHandler.

This is how we do it.  First add the interface to our class.

public class MyErrorHandler : IErrorHandler, IContractBehavior
{
...

Now implement the interface, adding our implementation of IErrorHandler to the collection of ErrorHandlers.

public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
	dispatchRuntime.ChannelDispatcher.ErrorHandlers.Add(this);
}

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

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

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

Now the final part of the wiring up is to make MyErrorhandler an attribute

public class MyErrorHandler : Attribute, IErrorHandler, IContractBehavior

and apply it to our WCF Service interface

 [ServiceContract]
 [MyErrorHandler]
 public interface IMyService
    {
      ... my interface methods

That’s it. There is an even cleaner way of wiring up the MyErrorHandler class – detail in my next blog to come.