以下を検討してください。
public interface IService
{
void DoSomething(object arg);
void DoSomethingElse(object arg, bool anotherArg);
bool AndDoYetMoreStuff(object arg, object[] moreArgs);
}
public class Service : IService
{
public void DoSomething(object arg){}
public void DoSomethingElse(object arg, bool anotherArg){}
public bool AndDoYetMoreStuff(object arg, object[] moreArgs)
{
return true;
}
}
public class ServiceRetryProxy : IService
{
const int retryLimit = 3;
private readonly IService _service;
public ServiceRetryProxy(IService service)
{
_service = service;
}
private void RetryOnException(Action<IService> ctx)
{
ReconnectOnException(service =>
{
ctx(service);
return new object();
});
}
private T RetryOnException<T>(Func<IService, T> ctx)
{
var counter = 0;
Exception lastException = null;
while (counter < retryLimit)
{
try
{
return ctx(_service);
}
catch (Exception ex)
{
lastException = ex;
counter++;
}
}
throw lastException;
}
public void DoSomething(object arg)
{
ReconnectOnException(x => x.DoSomething(arg));
}
public void DoSomethingElse(object arg, bool anotherArg)
{
ReconnectOnException(x => x.DoSomethingElse(arg, anotherArg));
}
public bool AndDoYetMoreStuff(object arg, object[] moreArgs)
{
return ReconnectOnException(x => x.AndDoYetMoreStuff(arg, moreArgs));
}
}
これに関する問題は、インターフェイスのすべてのメソッドに対してプロキシ メソッドを作成する必要があることです。特定のインターフェイスのすべてのメソッドに RetryOnException (またはその他のロジック) を適用できるように、より「動的な」ソリューションが必要です。現在、Castle DynamicProxy を検討していますが、他に選択肢がある場合はどうなりますか?