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;
}