I would use unity interface/virtualmethod interception.
_unityContainer.AddNewExtension<Interception>();
_unityContainer.RegisterType<ITestCaching, TestCaching>(
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<PolicyInjectionBehavior>());
_unityContainer.RegisterType<XRepository>(
new Interceptor<VirtualMethodInterceptor>(),
new InterceptionBehavior<PolicyInjectionBehavior>());
I use policy injection behavior so that I can use Attributes to add the additional behavior.
custom attributes involved in interception will need to inherit HandlerAttribute
and implement:
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new RetryCallHandler(container, ConfigurationName);
}
The behavior will be implemented in the class that implements ICallHandler
public class RetryCallHandler : ICallHandler, IDisposable
{
public IMethodReturn Invoke(IMethodInvocation args, GetNextInterceptionBehaviorDelegate getNext)
{
Exception exception = null;
int retryCounter = MAX_RETRIES;
do
{
exception = null;
try
{
var intercepted = getNext();
IMethodReturn methodReturn = intercepted(args, getNext);
return methodReturn;
}
catch (Exception ex)
{
exception = ex;
}
}while(exception!=null && retryCounter-- > 0);
return args.CreateExceptionMethodReturn(exception);
}
}
I haven't compiled or tested the above code.
The only problems that I foresee are GetNextInterceptionBehaviorDelegate in case you have multiple interceptions.
You can manage the order of your call handlers so just make sure that this is the last in the chain.