Prism通过反射机制自动注册对话视图模型
摘要说明
在使用WPF+Prism开发中,有时会需要使用到一些弹窗服务,而在Prism当中,我们使用Dialog是需要注入到IOC容器当中的,传统的写法如下:
而当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的视图模型中即可使用我们定义好的特性
程序在App.xaml.cs中初始化中就会通过反射自动找出含有该特性的类,并为我们注入到IOC中
写在最后
依据上面例子,还有很多场景可以利用反射+特性的形式为我们解决相关重复性劳动力的问题,思维打开,学会举一反三,例如我们还可以设计出自动生成菜单目录的方法,如果有需要,后续我再继续更新。