I have a requirement to log each method call in a WCF service, and any exceptions thrown. This has led to a lot of redundant code, because each method needs to include boilerplate similar to this:
[OperationContract]
public ResultBase<int> Add(int x, int y)
{
var parameters = new object[] { x, y }
MyInfrastructure.LogStart("Add", parameters);
try
{
// actual method body goes here
}
catch (Exception ex)
{
MyInfrastructure.LogError("Add", parameters, ex);
return new ResultBase<int>("Oops, the request failed", ex);
}
MyInfrastructure.LogEnd("Add", parameters);
}
Is there a way I can encapsulate all this logic into an attribute MyServiceLoggingBehaviorAttribute, which I could apply to the service class (or methods) like this:
[ServiceContract]
[MyServiceLoggingBehavior]
public class MyService
{
}
Note #1
I realize that this can be done using Aspect-oriented programming, but in C# the only way to do this is to modify bytecode, which requires the use of a third-party product like PostSharp. I would like to avoid using commercial libraries.
Note #2
Note that Silverlight applications are the primary consumers of the service.
Note #3
WCF trace logging is a good option in some cases, but it doesn’t work here because, as noted above, I need to inspect, and in the case of an exception change, the return value.
Yes, it is possible to encapsulate this kind of logging, using the extensibility points built into WCF. There are actually multiple possible approaches. The one I’m describing here adds an
IServiceBehavior, which uses a customIOperationInvoker, and does not require any web.config modifications.There are three parts to this.
IOperationInvoker, which wraps the method invocation in the required logging and error-handling.IOperationBehaviorthat applies the invoker from step 1.IServiceBehavior, which inherits fromAttribute, and applies the behavior from step 2.Step 1 – IOperationInvoker
The crux of IOperationInvoker is the
Invokemethod. My class wraps the base invoker in a try-catch block:Step 2 – IOperationBehavior
The implementation of IOperationBehavior simply applies the custom dispatcher to the operation.
Step 3 – IServiceBehavior
This implementation of
IServiceBehaviorapplies the operation behavior to the service; it should inherit fromAttributeso that it can be applied as an attribute to the WCF service class. The implementation for this is standard.