为相当模棱两可的标题道歉,但我想要实现的目标可能在代码中更好地说明。
我有一个 WCF 客户端。当我调用方法时,我想将每个调用包装在一些错误处理代码中。因此,我没有直接公开方法,而是在客户端类上创建了以下帮助函数:
public T HandleServiceCall<T>(Func<IApplicationService, T> serviceMethod)
{
try
{
return serviceMethod(decorator);
}
[...]
}
客户端代码像这样使用它:
service.HandleServiceCall(channel => channel.Ping("Hello"));
并且对 Ping 的调用很好地包含在一些尝试处理任何错误的逻辑中。
这很好用,只是我现在需要知道服务上实际调用了哪些方法。最初,我希望只检查Func<IApplicationService, T>
使用表达式树,但没有走得太远。
最后,我选择了一个装饰器模式:
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")
}
}
}
装饰器本身:
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);
}
}
它真的很笨重,而且代码很多。有没有更优雅的方式来做到这一点?