In order to pass data to your Fallback method you need to take advantage of the Context
For the sake of simplicity let me simplify your implementation a bit to show you how to use the Context
:
private int GetResponse(int request)
{
return request + 1;
}
private int GetResponseFallback(int request)
{
return request + 2;
}
So I've just get rid of the IExecuter
, Request
and Response
concepts to keep the sample code as simple as possible.
To pass data to your GetResponseFallback
we need to change the parameter like this:
private const string requestKey = "request";
private int GetResponseFallback(Context ctx)
{
var request = (int)ctx[requestKey];
return request + 2;
}
So, we have retrieved the request
data from the Context
. Now we need to somehow pass that information to the GetResponseFallback
call.
The good thing is that we don't need to modify the GetResponse
. On the other hand we need to adjust the Process
method like this:
private int Process(int request)
{
var contextData = new Dictionary<string, object> { { requestKey, request } };
_policy = Policy<int>
.Handle<Exception>()
.Fallback((ctx) => GetResponseFallback(ctx), (_, __) => { });
return _policy.Execute((_) => GetResponse(request), contextData);
}
- We have created a
contextData
dictionary to store the input parameter in it
- We have used a special overload of the Fallback where we have to define two delegates:
- Unfortunately there is no overload where we have to provide only a
Action<Context> fallbackAction
parameter
public static FallbackPolicy Fallback(this PolicyBuilder policyBuilder, Action<Context> fallbackAction, Action<Exception, Context> onFallback)
- Because we don't want to do anything inside the
onFallback
that's why I defined that like this (_,__) => { }
- We have called a special overload of Execute, which has the following syntax:
public void Execute(Action<Context> action, IDictionary<string, object> contextData)
- Because we are not passing the Context parameter to the
GetResponse
directly that's why we can use here the discard operator (_) => GetResponse(...)
One last important thing: I had to change the _policy
variable type to Policy<int>
to indicate the return type.
For the sake of completeness here is the full source code:
private static Policy<int> _policy;
static void Main(string[] args)
{
Console.WriteLine(Process(1));
}
private const string requestKey = "request";
static int Process(int request)
{
var contextData = new Dictionary<string, object> { { requestKey, request } };
_policy = Policy<int>
.Handle<Exception>()
.Fallback((ctx) => GetResponseFallback(ctx), (_, __) => { });
return _policy.Execute((_) => GetResponse(request), contextData);
}
static int GetResponse(int request)
{
throw new Exception();
return request + 1;
}
static int GetResponseFallback(Context ctx)
{
var request = (int)ctx[requestKey];
return request + 2;
}