Polly Fallback策略中动态委托的实现咨询
嘿,针对你在PolicyRegistry里复用全局策略、实现fallbackPolicy的需求,我给你梳理一套清晰的实现方案,完全贴合你要的「主逻辑成功不触发降级,失败则先执行自定义onFail处理、再触发预定义fallback」的效果~
实现思路与代码示例
核心逻辑很明确:我们需要一个FallbackPolicy类,它能包裹主逻辑(Action/Func),捕获执行异常,异常时先跑你传入的自定义失败处理程序,再触发从PolicyRegistry里拿的全局预定义降级动作。
1. 定义FallbackPolicy核心类
这个类要支持无返回值和有返回值的主逻辑,同时允许传入多个自定义失败处理:
public class FallbackPolicy { // 从全局PolicyRegistry获取的预定义降级动作 private readonly Action<Exception> _globalFallbackAction; // 构造函数:传入全局降级动作(直接从PolicyRegistry取就行) public FallbackPolicy(Action<Exception> globalFallbackAction) { _globalFallbackAction = globalFallbackAction ?? throw new ArgumentNullException(nameof(globalFallbackAction)); } // 处理无返回值的Action public void Execute(Action mainAction, params Action<Exception>[] customFailHandlers) { try { // 执行主逻辑 mainAction(); } catch (Exception ex) { // 先执行所有自定义的失败处理程序 foreach (var handler in customFailHandlers) { handler?.Invoke(ex); } // 再触发全局预定义的降级策略 _globalFallbackAction(ex); } } // 处理有返回值的Func public TResult Execute<TResult>(Func<TResult> mainFunc, params Action<Exception>[] customFailHandlers) { try { return mainFunc(); } catch (Exception ex) { // 先跑自定义失败处理 foreach (var handler in customFailHandlers) { handler?.Invoke(ex); } // 触发全局降级,这里如果需要降级返回值,可以调整_globalFallbackAction为Func<Exception, TResult> _globalFallbackAction(ex); return default; // 或者根据你的需求返回降级后的结果 } } }
2. 结合PolicyRegistry复用全局策略
假设你已经在PolicyRegistry里注册了全局的降级动作,我们可以直接拿来用:
// 初始化PolicyRegistry并注册全局降级策略 var policyRegistry = new PolicyRegistry(); policyRegistry.Add("GlobalFallback", new Action<Exception>(ex => { // 这里写你的全局降级逻辑:比如记录系统日志、发送告警、返回默认值等 Console.WriteLine($"[全局降级触发] 错误信息:{ex.Message}"); // 可以加更多全局统一逻辑,比如调用告警API })); // 实例化FallbackPolicy时,从注册表取出全局策略 var fallbackPolicy = new FallbackPolicy(policyRegistry.Get<Action<Exception>>("GlobalFallback"));
3. 实际使用:传入两个自定义onFail处理程序
现在你可以传入任意数量的失败处理程序,比如一个记录详细日志,一个发送内部告警:
// 模拟可能失败的主逻辑 Action riskyMainAction = () => { Console.WriteLine("正在执行主业务逻辑..."); // 模拟失败场景 throw new InvalidOperationException("数据库连接超时!"); }; // 自定义失败处理1:记录详细错误堆栈 Action<Exception> logDetailedError = ex => { Console.WriteLine($"[自定义日志] 错误详情:{ex.ToString()}"); }; // 自定义失败处理2:发送内部团队告警 Action<Exception> sendTeamAlert = ex => { Console.WriteLine($"[告警通知] 业务操作失败,错误:{ex.Message},请排查!"); }; // 执行主逻辑,传入两个自定义失败处理 fallbackPolicy.Execute(riskyMainAction, logDetailedError, sendTeamAlert);
4. 进阶:支持有返回值的降级(可选)
如果你的主逻辑有返回值,且降级需要返回特定结果,可以调整成带返回值的版本:
public class FallbackPolicy<TResult> { private readonly Func<Exception, TResult> _globalFallbackFunc; public FallbackPolicy(Func<Exception, TResult> globalFallbackFunc) { _globalFallbackFunc = globalFallbackFunc ?? throw new ArgumentNullException(nameof(globalFallbackFunc)); } public TResult Execute(Func<TResult> mainFunc, params Action<Exception>[] customFailHandlers) { try { return mainFunc(); } catch (Exception ex) { foreach (var handler in customFailHandlers) { handler?.Invoke(ex); } // 降级逻辑返回指定结果 return _globalFallbackFunc(ex); } } }
使用示例:
// 注册有返回值的全局降级策略 policyRegistry.Add("GlobalFallbackWithResult", new Func<Exception, string>(ex => { Console.WriteLine("[全局降级] 返回默认数据"); return "默认兜底数据"; })); var fallbackPolicyWithResult = new FallbackPolicy<string>(policyRegistry.Get<Func<Exception, string>>("GlobalFallbackWithResult")); string result = fallbackPolicyWithResult.Execute(() => { throw new InvalidOperationException("获取数据失败"); }, logDetailedError, sendTeamAlert); Console.WriteLine($"最终返回结果:{result}");
关键细节说明
- 执行顺序:主逻辑失败时,会先按你传入的顺序执行所有自定义
onFail处理程序,再触发全局预定义的fallback动作; - 全局复用:通过PolicyRegistry管理全局降级策略,所有地方都可以复用同一套逻辑,方便统一修改;
- 灵活性:支持无返回值和有返回值的场景,自定义失败处理可以传任意数量,满足不同业务需求;
内容的提问来源于stack exchange,提问作者Kal
相关产品推荐
相关产品推荐

