我们有一个用C#/WPF/Prism构建的相当大的应用程序。应用程序有几个静态模块和未知数量的动态加载模块。
我的影响范围是静态模块和shell。
我被要求实现一个将重启shell的特性,但只有在查询所有当前打开的模块是否允许重启之后。如果至少有一个模块表示不允许(例如:仍然未保存的更改),则重新启动将被推迟。
现在shell和模块通过EventAggregator
进行通信。这意味着我可以发布一个事件,然后查看是否有任何订阅服务器拒绝或允许重新启动。
这对我可以更改的所有模块都很有效。但是,我不能改变动态模块(不同的团队,不同的源代码管理)。
其中一个要求是,如果任何模块不支持此新特性,则应将其视为拒绝重新启动。
明显的问题是,我如何发现,有人没有订阅该活动?
虽然所有的viewmodels都实现了IViewModel
接口,但我看不出有多少viewmodels当前存在(所以我至少可以看看是不是所有的viewmodels都允许,或者只是缺少了一些答案)。
我可能会知道,有多少模块支持它,但即使这样也不能说明有多少viewmodels当前被视图打开/存在/使用。
是否有一种方法可以在不更改所述viewmodel的情况下发现活动viewmodel是否不支持此功能?
在任何给定时刻,您都可以查看IRegionManager.Regions以查找所有现有区域。集合中的每个IRegion都有IRegion.ActiveViews,它给出了该区域中当前所有活动视图的列表。然后可以检查每个视图(它是一个对象)是否附加了某个属性或实现了某个接口。然后,如果视图是FrameworkElement,您还可以检查它的DataContext。
如果您发现了一个没有属性/接口的视图,则该视图不支持重新启动。如果视图具有属性/接口,则查询该接口。
如果创建其他(有范围的)区域经理,则需要跟踪他们。您维护一个活动区域管理器列表,最初只包含附加到shell的区域管理器。在检查视图时,如果视图是FrameworkElement并且附加了区域管理器,并且附加的区域管理器不在列表中,则将其添加到列表中,并使用相同的算法检查由该区域管理器控制的视图。