かなりあいまいなタイトルについてお詫びしますが、私が達成しようとしていることは、おそらくコードでより適切に述べられています。
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);
}
}
それは本当に不格好で、かなり多くのコードです。これを行うためのよりエレガントな方法はありますか?