Apologies for the fairly ambiguous title but what I'm trying to achieve is probably better stated in code.
I have a WCF client. When I'm calling methods I would like to wrap each call in some error handling code. So, instead of exposing the methods directly, I've created the following helper function on the client class:
public T HandleServiceCall<T>(Func<IApplicationService, T> serviceMethod)
{
try
{
return serviceMethod(decorator);
}
[...]
}
And the client code uses it like this:
service.HandleServiceCall(channel => channel.Ping("Hello"));
And the call to Ping gets nicely wrapped in some logic that will try to handle any errors.
This works great except that I now have a requirement to know which methods are actually being called on the service. Initially , I was hoping to just inspect the Func<IApplicationService, T>
using Expression trees but didn't get very far.
Finally, I settled on a Decorator pattern:
public T HandleServiceCall<T>(Func<IApplicationService, T> serviceMethod)
{
var decorator = new ServiceCallDecorator(client.ServiceChannel);
try
{
return serviceMethod(decorator);
}
[...]
finally
{
if (decorator.PingWasCalled)
{
Console.Writeline("I know that Ping was called")
}
}
}
And the Decorator itself:
private class ServiceCallDecorator : IApplicationService
{
private readonly IApplicationService service;
public ServiceCallDecorator(IApplicationService service)
{
this.service = service;
this.PingWasCalled = new Nullable<bool>();
}
public bool? PingWasCalled
{
get;
private set;
}
public ServiceResponse<bool> Ping(string message)
{
PingWasCalled = true;
return service.Ping(message);
}
}
It's really clunky and quite a lot of code. Is there a more elegant way of doing this?
You could use an Expression, then inspect the body.
Something like
public T HandleServiceCall<T>(Expression<Func<IApplicationService, T>> serviceMethod)
{
try
{
var func = serviceMethod.Compile();
string body = serviceMethod.Body.ToString();
return func(new ConcreteAppService());
}
catch(Exception ex)
{
...
}
}