ModuleAttribute(按需延迟加载)
ModuleAttribute 是 Prism 框架中用于标识模块的属性。通过使用 ModuleAttribute,可以将模块与特定的模块目录进行关联,从而使 Prism 应用程序能够动态加载和初始化模块。
在使用 WPF ModuleAttribute 时,需要将该属性应用于模块类,并指定模块的模块目录路径。例如:
ModuleName:获取或设置模块的名称
OnDemand:获取或设置指示是否应按需加载模块的值。
StartupLoaded :获取或设置一个值,该值指示是否应在启动时加载模块- [Module(ModuleName = "MyModule", OnDemand = true)]
- public class MyModule : IModule
- {
- // 模块的初始化和加载逻辑
- }
复制代码 利用特性和反射向IOC容器中注册服务
案列:
自动初始化特性:- /// <summary>
- /// 标注类型的生命周期是否自动初始化
- /// AttributeTargets.Class自定义特性的对象
- /// AllowMultiple :是否允许被多次使用
- /// </summary>
- [<strong>AttributeUsage</strong>(AttributeTargets.Class, AllowMultiple = false)]
- public class ExposedServiceAttribute : Attribute
- {
- public Lifetime LiftTime { get; set; }
- public bool AutoInitialize { get; set; }
- public Type[] Types { get; set; }
- public ExposedServiceAttribute(Lifetime liftTime = Lifetime.Transient, params Type[] types)
- {
- LiftTime = liftTime;
- Types = types;
- }
- }
复制代码- public enum Lifetime
- {
- /// <summary>
- /// 单列
- /// </summary>
- Singleton,
- /// <summary>
- /// 多列
- /// </summary>
- Transient
- }
复制代码 AttributeUsage 描述了如何使用一个自定义特性类。它规定了特性可应用到的项目的类型。
规定该特性的语法如下:- [AttributeUsage(
- validon,
- AllowMultiple=allowmultiple,
- Inherited=inherited
- )]
复制代码- validon:自定义特性的对象,可以是类、方法、属性等对象(默认值是 <em>AttributeTargets.All)<br></em>
复制代码- AllowMultiple:是否允许被多次使用(默认值为false:单用的)
复制代码- Inherited:是否可被派生类继承(默认值为false:不能)<br><br><br><strong>依赖注入扩展类:</strong><br>加载模块时,实例化标注为ExposedServiceAttriubute特性的类
复制代码- /// <summary>
- /// 加载模块时,实例化标注为ExposedServiceAttriubute特性的类
- /// </summary>
- public static class DependencyExtension
- {
- private static List<Type> GetTypes(Assembly assembly)
- {
- var result = assembly.GetTypes().Where(t => t != null && t.IsClass && !t.IsAbstract &&
- t.CustomAttributes.Any(p => p.AttributeType == typeof(ExposedServiceAttribute))).ToList();
- return result;
- }
- /// <summary>
- /// 扩展IContainerRegistry接口的注册类型的功能
- /// </summary>
- /// <param name="container"></param>
- /// <param name="assembly"></param>
- public static void RegisterAssembly(this IContainerRegistry container, Assembly assembly)
- {
- var list = GetTypes(assembly);
- foreach (var type in list)
- {
- RegisterAssembly(container, type);
- }
- }
- private static IEnumerable<ExposedServiceAttribute> GetExposedServices(Type type)
- {
- var typeInfo = type.GetTypeInfo();
- return typeInfo.GetCustomAttributes<ExposedServiceAttribute>();
- }
- public static void RegisterAssembly(IContainerRegistry container, Type type)
- {
- var list = GetExposedServices(type).ToList();
- foreach (var item in list)
- {
- if (item.LiftTime == Lifetime.Singleton)
- {
- container.RegisterSingleton(type);//注册单例
- }
- foreach (var IType in item.Types)
- {
- if (item.LiftTime == Lifetime.Singleton)
- {
- container.RegisterSingleton(IType, type);//以接口注册单例
- }
- else if (item.LiftTime == Lifetime.Transient)
- {
- container.Register(IType, type);//以接口注册多例
- }
- }
- }
- }
- /// <summary>
- /// 初始化程序集中所有标注为ExposedServiceAttriubute特性的类,要求单例具自动加载AutoInitialize=true
- /// </summary>
- /// <param name="container"></param>
- /// <param name="assembly"></param>
- public static void InitializeAssembly(this IContainerProvider container, Assembly assembly)
- {
- var list = GetTypes(assembly);
- foreach (var item in list)
- {
- InitializeAssembly(container, item);
- }
- }
- private static void InitializeAssembly(IContainerProvider container, Type type)
- {
- var list = GetExposedServices(type);
- foreach (var item in list)
- {
- if (item.LiftTime == Lifetime.Singleton && item.AutoInitialize)
- {
- container.Resolve(type);
- }
- }
- }
- }
复制代码
图片模块IModule中配置,意思是在加载这个模块的时候会自动注册和初始化带有该模块中有ExposedServiceAttribute 特性的类- [Module(ModuleName = ModuleName.ImageModuleProfile, OnDemand = true)]
- public class ImageModuleProfile : IModule
- {
- public void OnInitialized(IContainerProvider containerProvider)
- {
- <strong>containerProvider.InitializeAssembly(Assembly.GetExecutingAssembly());</strong>
- containerProvider.Resolve<IRegionManager>().RegisterViewWithRegion<ImageView>(ContentControlName.MainmoduleImagemoduleReginName);
- }
- public void RegisterTypes(IContainerRegistry containerRegistry)
- {
- <strong>containerRegistry.RegisterAssembly(Assembly.GetExecutingAssembly());</strong>
- containerRegistry.RegisterForNavigation<ImageView, ImageViewModel>();
- }
- }
复制代码
使用:- /// <summary>
- /// 显示16位探测器图像的模型
- /// </summary>
- <strong>[ExposedService(Lifetime.Singleton, typeof(IDetectorDisplayModel))]
- </strong>public class DetectorDisplayModel : IDetectorDisplayModel
- {
- }
复制代码
上面我们知道了如何利用特性的方式去注册服务,下面用ExposedServiceAttribute去注册Prism里面的功能- <strong> [ExposedServiceAttribute(Lifetime.Singleton, AutoInitialize = true)]
- </strong>public sealed class PrismProvider
- {
- public PrismProvider(
- IContainerExtension container,
- IRegionManager regionManager,
- IDialogService dialogService,
- IEventAggregator eventAggregator,
- IModuleManager moduleManager)
- {
- LanguageManager = language;
- Container = container;
- RegionManager = regionManager;
- DialogService = dialogService;
- EventAggregator = eventAggregator;
- ModuleManager = moduleManager;
- }
- /// <summary>
- /// 容器
- /// </summary>
- public static IContainerExtension Container { get; private set; }
- /// <summary>
- /// 区域管理器接口
- /// </summary>
- public static IRegionManager RegionManager { get; private set; }
- /// <summary>
- /// 对话框管理器
- /// </summary>
- public static IDialogService DialogService { get; private set; }
- /// <summary>
- /// 事件聚合器
- /// </summary>
- public static IEventAggregator EventAggregator { get; private set; }
- /// <summary>
- /// 模块管理器
- /// </summary>
- public static IModuleManager ModuleManager { get; private set; }
- }
复制代码 使用:- //第一步,加载模块
- <strong> PrismProvider</strong>.ModuleManager.LoadModule(ModuleName.LoginModuleProfile);
- //第二步,导航区域
- <strong>PrismProvider</strong>.RegionManager.RequestNavigate(ContentControlName.MainWindowReginName, ViewNames.LoginView);
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |