我在blazor上做spa,关闭View并在服务上调用Dispose方法时,并没有完全清除,因为下次切换到同一个View时,不会调用该服务的构造函数。实际项目中的服务被声明为Scoped。创建了最简单的例子。
关于这个例子的一点解释。所有属性都与 ReactiveUI 相关联。有一个主页 - MainView 和第二个 ProfileView,它有一个带有两个选项卡的 TabControl:FirstTabView 和 SecondTabView。所有的 View 都被声明为 Transient 服务,一个 ProfileService 被声明为 Scoped。
主视图行为。
有一个 Number 属性,它在构造函数 (MainViewModel) 中无限递增,直到调用 Dispose 方法。此方法是为瞬态寿命示例而设计的。
个人资料视图行为
在 ProfileService.LoadProfileAsync 服务中调用第一次渲染后 ui(OnAfterRenderAsync) 假加载。加载后,它会显示 ProfileView 的创建时间、服务的创建时间(检查是否每次都创建)以及上次更新的时间。第一个选项卡显示名称作为示例,第二个选项卡显示从 ProfileView 不断更新的连接。
我的问题
在 TabControl 中的选项卡(First、Second)之间切换时,属性订阅被移除,一切正常,但如果我将 ProfileView 留给 MainView,那么我需要释放 ProfileService 本身,因为我不需要它。它是“释放”的,但是下次它点击 ProfileView 页面时,不会调用此服务的构造函数。并且由于没有从中调用构造函数,所以所有订阅都无法接收到它们的数据,因为在这个服务的 Dispose 方法中,我为每个字段调用了 OnCompleted,也就是我完成了以后的更新。
问题
如果之前调用了Dispose方法,为什么切换到ProfileView时没有调用ProfileService构造函数?

这里只有一个人回答我。一般来说,在 wasm 应用程序中,作用域和单例之间没有区别。要管理作用域服务的生命周期,您需要从 OwningComponentBase 继承组件(有一个通用实现)。如果我们从这个组件继承,那么我们清除所有在运行期间收到的服务。乍一看,一切都很好,但当我有一个有 n 个窗口并且每个都有 k 个窗口的主窗口时就不行了。如果每个人都继承自 OwningComponentBase,那么会得到这个类的 n + k(可能)个实例,这不适合我。
到目前为止,我已经找到了 2 个解决方案:
家庭虚拟机
主组件 MainView.razor.cs
子组件 FirstTabView.razor.cs
也许有更优雅的解决方案,但目前我不知道/没有找到它们。