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
{
}