Loading

Prism通过反射机制自动注册对话视图模型

摘要说明

在使用WPF+Prism开发中,有时会需要使用到一些弹窗服务,而在Prism当中,我们使用Dialog是需要注入到IOC容器当中的,传统的写法如下:

image-20221115222944124

而当Dialog过多时或者需要新增一个弹窗时,每次都需要写一行这个注册,属实有点麻烦,所以我查阅了一下Prism源码,写了一个自动注册的扩展方法。

扩展IContainerRegistry通过类型注入对话服务

public static class IContainerRegistryDialogExtensions
    {
        public static void RegistryDialogByType(this IContainerRegistry registry, Type viewType, Type viewModelType, string viewName = null)
        {
            if (string.IsNullOrWhiteSpace(viewName))
                viewName = viewType.Name;

            ViewModelLocationProvider.Register(viewType.ToString(), viewModelType);
            registry.RegisterForNavigation(viewType, viewName);
        }

        public static void RegistryDialogByType(this IContainerRegistry registry, Type viewType, string viewName = null)
        {
            if (string.IsNullOrWhiteSpace(viewName))
                viewName = viewType.Name;
            registry.RegisterForNavigation(viewType, viewName);
        }
    }

编写自动注入的特性

public class DialogConfigureAttribute : System.Attribute
    {
        public Type View { get; set; }

        public string ViewName { get; set; }

        public DialogConfigureAttribute(Type viewType, string viewName = null)
        {
            this.View = viewType;
            this.ViewName = viewName;
        }
    }

该特性可以根据项目实际情况来定,其中视图类型视图名称是必须的

编写自动注入方法

public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            ....
            //调用自动注入方法
            DialogConfigure(containerRegistry);
        }

        /// <summary>
        /// 注册有Model的对话服务
        /// </summary>
        /// <param name="containerRegistry"></param>
        private void DialogConfigure(IContainerRegistry containerRegistry)
        {
            var allType = Assembly.GetCallingAssembly().GetExportedTypes().Where(t => t.IsDefined(typeof(DialogConfigureAttribute)));
            foreach (var item in allType)
            {
                var dialogConfigure = item.GetCustomAttribute(typeof(DialogConfigureAttribute)) as DialogConfigureAttribute;
                containerRegistry.RegistryDialogByType(dialogConfigure.View, item, dialogConfigure.ViewName);
            }
        }

使用特性

后续在所有Dialog的视图模型中即可使用我们定义好的特性

image-20221115223737775

程序在App.xaml.cs中初始化中就会通过反射自动找出含有该特性的类,并为我们注入到IOC中

写在最后

依据上面例子,还有很多场景可以利用反射+特性的形式为我们解决相关重复性劳动力的问题,思维打开,学会举一反三,例如我们还可以设计出自动生成菜单目录的方法,如果有需要,后续我再继续更新。

posted @ 2022-11-15 22:42  傲慢与偏见luc  阅读(554)  评论(0编辑  收藏  举报