wcf Handling exceptions Decoupling ErrorHandlerAttribute registering from the service implementation


Example

To decouple and reuse the same error logging code for all your services you need two boilerplate classes and tuck them away in a library somewhere.

ErrorhandlerAttribute implementing IServiceBehavior. FaultErrorhandler implementing IErrorhandler which logs all the exceptions.

[AttributeUsage(AttributeTargets.Class)]
public class ErrorHandlerAttribute : Attribute, IServiceBehavior
{
    Type mErrorType;
    public ErrorHandlerAttribute(Type t)
    {
        if (!typeof(IErrorHandler).IsAssignableFrom(t))
            throw new ArgumentException("Type passed to ErrorHandlerAttribute constructor must inherit from IErrorHandler");
        mErrorType = t;
    }

    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
        {
            dispatcher.ErrorHandlers.Add((IErrorHandler)Activator.CreateInstance(mErrorType));
        }
    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
    }
}


class FaultErrorHandler : IErrorHandler
{
    public bool HandleError(Exception error)
    {
        // LOG ERROR
        return false; // false so the session gets aborted
    }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {
    }
}

Then in your service implementation add the ErrorHandler Attribute passing in the Type instance of FaultErrorHandler. ErrorHandler will construct an instance from that type on which HandleError is called.

[ServiceBehavior]
[ErrorHandler(typeof(FaultErrorHandler))]
public class MyService : IMyService
{
}