c# – 跨所有视图模型处理令牌到期事件的策略
应用程序架构是:MVVM [Views – > ViewModels] – >存储库 – > API.
API层可以抛出TokenExpiredException异常,我们最终希望在UI层处理该异常(通过显示消息框并重定向到登录). 今天,我们的虚拟机与存储库交互,如下所示: SomeCommand { await _repo.DoSomethingAsync(); } 我的问题是找到一个好的模式来处理API层的这个例外.我可以想到3种方法: 1)在BaseViewModel方法中包装每个存储库调用,该方法负责捕获和处理此视图模型无关的异常. SomeCommand { await base.RepoRequest(() => _repo.DoSomethingAsync()); } BaseViewModel将具有的位置: RepoRequest(action) { try { action() } catch (TokenExpiredException) { // show message box // redirect } 任何其他异常(例如验证错误)都将在VM中处理.我在这里看到的问题是忘记使用这种模式太容易了.我可能会直接在某处调用存储库并错过处理异常. 2)每个VM都捕获此异常 SomeCommand { try { await _repo.DoSomethingAsync(); } catch (InvalidUsernameException) { ... } catch (TokenExpiredException) { // show message box // redirect } 与1)没有什么不同,相同的问题,需要更多的代码重复. 3)使用事件聚合器将消息从API层发布到BaseViewModel. ApiRequest { var response = await _httpClient.ExecuteAsync<..>(...); if (response.ErrorId == "InvalidUsername") throw new InvalidUsernameException(); else if (response.ErrorId == "TokenExpired") EventAggregator.Publish(new TokenExpiredException()); } 和BaseViewModel onMessage(TokenExpiredException e) { // show message box // redirect } 这样做的好处是可以让所有虚拟机(但基站)无需接线. 有没有人建议如何干净地实现这个功能? 解决方法
我不得不弄清楚同样的问题,但我正在使用WCF和城堡wcf设施,这对我有帮助,因为该设施已经有
point of extension用于拦截呼叫.所以我刚刚创建了自定义的AbstractWcfPolicy并拦截了我想要管理的所有异常.
根据相同的想法,您可以考虑使用基于castle dynamic proxy的代理类,这样您的调用将保持等待_repo.DoSomethingAsync();但在木材下你的ExceptionInterceptor将拦截所有异常,并做任何你想做的事情: [Serializable] public class Interceptor : IInterceptor { public void Intercept(IInvocation invocation) { Console.WriteLine("Before target call"); try { invocation.Proceed(); } catch(Exception) { Console.WriteLine("Target threw an exception!"); throw; } finally { Console.WriteLine("After target call"); } } } 然后你可以抛弃一些你可能想要抛出的异常,对于某些异常或全部,你也可以实现一个发布 – 订阅(全局消息代理,messenger in MVVM Light)机制,你推动异常,然后在您的应用程序的任何一点,您可以订阅这些错误并执行某些操作(记录,以不显眼的方式向用户显示错误等等). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |