【发布时间】:2011-08-02 23:00:41
【问题描述】:
为这个相当模棱两可的标题道歉,但我想要实现的目标可能在代码中更好地说明。
我有一个 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);
}
}
它真的很笨重,而且代码很多。 有没有更优雅的方式来做到这一点?
【问题讨论】:
-
你在哪里创建装饰器?
-
表达式树应该是要走的路。你能显示代码并告诉我们问题所在吗?
-
听起来像是 PostSharp 的工作。
-
@smartcaveman:与
HandleServiceMethod同父类中的私有类 -
@Daniel:这就是我首先尝试但在第一个障碍中失败的方法 - 将
Func转换为Expression。