This week I've been working on a WCF webservice and I wanted to get dependency injection going and leverage interception in order to nicely handle logging, exceptions and some performance measurement.
Although I prefer Ninject, I had to go with Unity for the IoC container. Now - the sweet thing is this NuGet package Unity.Wcf.
It's super easy to set up. What will happen is that your services will be served from a factory, that you populate by setting up the container. Check out this website to get going with this awesome package:
http://unitywcf.codeplex.com/ and get it from NuGet.
So once you got that going, you can add interceptors to it to get some pre- and post method call behavior.
What I wanted to do is convert exceptions to SaupFaults. Piece of cake some custom behavior. So here's the factory that is generated by installing the unity.wcf factory - with the registration of the service + the behaviors:
protected override void ConfigureContainer(IUnityContainer container)
{
// Enable Interception
container.AddNewExtension<Interception>();
// Register the wagenlijstservice
container.RegisterType<ISomeService, MyService>(
new Interceptor(new InterfaceInterceptor()),
new InterceptionBehavior<TransformExceptionToFaultExceptionBehavior>(),
new InterceptionBehavior<ExceptionLoggingBehavior>(),
new InterceptionBehavior<PerformanceMeasureBehavior>(),
new InterceptionBehavior<LogBehavior>());
...
}
And this is the behavior itself:
public override IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
{
var methodReturn = getNext()(input, getNext);
if (methodReturn.Exception != null)
{
var fault = new SomeCustomFaultImplementation()
{
Code = methodReturn.Exception.GetType().Name,
Message = methodReturn.Exception.Message
};
throw new FaultException<SomeCustomFaultImplementation>(fault, fault.Message);
}
return methodReturn;
}
The WSDL I'm working with has a custom fault implementation so I had to respect that. The point is though, that if I find an exception in the methodReturn.Exception - I throw a FaultException immediately with input from the exception.
I'm quite happy with the solution. Another way of doing this is adding a new errorbehavior to the WCF service using attributes - as described here:
http://www.codeproject.com/Articles/26320/WCF-Error-Handling-and-Fault-Conversion . However - since I had the whole thing set up with interceptors already, I'm going with this one.