基于Prism DryIoc的WPF应用如何获取已注册导航视图列表
解答
实现原理
Prism的RegisterForNavigation本质是在注册视图类型时,会自动在容器的注册元数据中添加RegionManager.NavigationKeyProperty标识,值为导航名称(默认是视图类名,自定义注册名称时取你传入的参数),我们可以通过筛选带该标识的注册项拿到所有导航视图。
方法1:直接从DryIoc容器查询
该方法依赖DryIoc原生API,无需额外封装,适合不需要切换IoC容器的场景:
using DryIoc; using Prism.Ioc; using Prism.Regions; // 可在Prism应用初始化完成后任意位置调用 var dryIocContainer = ContainerLocator.Container.GetContainer(); var allNavigationViews = dryIocContainer.GetServiceRegistrations() .Where(reg => reg.Metadata?.ContainsKey(RegionManager.NavigationKeyProperty) == true) .Select(reg => new { // 导航时用的名称 NavigationName = reg.Metadata[RegionManager.NavigationKeyProperty].ToString(), // 对应的视图类型 ViewType = reg.ServiceType }) .ToList();
方法2:自定义注册封装(跨容器兼容)
如果后续可能切换Prism的IoC容器,或者不想依赖容器原生API,可以自己封装注册逻辑,统一存储导航视图注册信息:
- 先定义全局导航注册表和扩展方法
public static class NavigationRegistry { // 存储所有已注册的导航视图 public static List<(string NavigationName, Type ViewType)> RegisteredViews { get; } = new(); // 重写RegisterForNavigation扩展方法 public static void RegisterForNavigation<TView>(this IContainerRegistry containerRegistry, string navigationName = null) { var name = navigationName ?? typeof(TView).Name; RegisteredViews.Add((name, typeof(TView))); // 调用Prism原生的注册逻辑 Prism.Ioc.ContainerRegistryExtensions.RegisterForNavigation<TView>(containerRegistry, navigationName); } }
- 模块注册导航时替换为自定义的扩展方法即可,后续需要拿列表直接读取
NavigationRegistry.RegisteredViews即可。
注意事项
- 两种方法都支持自定义导航名称的注册场景,不会出现名称不匹配问题
- 方法1需要注意DryIoc和Prism的版本兼容性,大部分正式发布的版本都可正常使用
内容的提问来源于stack exchange,提问作者Alex R
相关产品推荐
相关产品推荐

