Friday, April 19, 2013

Using Unity+Interceptors with WCF services to transform exceptions to soap faults

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.

No comments:

Post a Comment