翼度科技»论坛 编程开发 .net 查看内容

2.Prism框架ModuleAttribute、IOC扩展、功能注册

4

主题

4

帖子

12

积分

新手上路

Rank: 1

积分
12
ModuleAttribute(按需延迟加载)
ModuleAttribute 是 Prism 框架中用于标识模块的属性。通过使用 ModuleAttribute,可以将模块与特定的模块目录进行关联,从而使 Prism 应用程序能够动态加载和初始化模块。
在使用 WPF ModuleAttribute 时,需要将该属性应用于模块类,并指定模块的模块目录路径。例如:
ModuleName:获取或设置模块的名称
OnDemand:获取或设置指示是否应按需加载模块的值。
StartupLoaded :获取或设置一个值,该值指示是否应在启动时加载模块
  1. [Module(ModuleName = "MyModule", OnDemand = true)]
  2. public class MyModule : IModule
  3. {
  4.     // 模块的初始化和加载逻辑
  5. }
复制代码
利用特性和反射向IOC容器中注册服务
案列:
自动初始化特性:
  1. /// <summary>
  2.     /// 标注类型的生命周期是否自动初始化
  3.     /// AttributeTargets.Class自定义特性的对象
  4.     /// AllowMultiple :是否允许被多次使用
  5.     /// </summary>
  6.     [<strong>AttributeUsage</strong>(AttributeTargets.Class, AllowMultiple = false)]
  7.     public class ExposedServiceAttribute : Attribute
  8.     {
  9.         public Lifetime LiftTime { get; set; }
  10.         public bool AutoInitialize { get; set; }
  11.         public Type[] Types { get; set; }
  12.         public ExposedServiceAttribute(Lifetime liftTime = Lifetime.Transient, params Type[] types)
  13.         {
  14.             LiftTime = liftTime;
  15.             Types = types;
  16.         }
  17.     }
复制代码
  1. public enum Lifetime
  2.     {
  3.         /// <summary>
  4.         /// 单列
  5.         /// </summary>
  6.         Singleton,
  7.         /// <summary>
  8.         /// 多列
  9.         /// </summary>
  10.         Transient
  11.     }
复制代码
AttributeUsage 描述了如何使用一个自定义特性类。它规定了特性可应用到的项目的类型。
规定该特性的语法如下:
  1. [AttributeUsage(
  2.    validon,
  3.    AllowMultiple=allowmultiple,
  4.    Inherited=inherited
  5. )]
复制代码
  1. validon:自定义特性的对象,可以是类、方法、属性等对象(默认值是 <em>AttributeTargets.All)<br></em>
复制代码
  1. AllowMultiple:是否允许被多次使用(默认值为false:单用的)
复制代码
  1. Inherited:是否可被派生类继承(默认值为false:不能)<br><br><br><strong>依赖注入扩展类:</strong><br>加载模块时,实例化标注为ExposedServiceAttriubute特性的类
复制代码
  1. /// <summary>
  2.     /// 加载模块时,实例化标注为ExposedServiceAttriubute特性的类
  3.     /// </summary>
  4.     public static class DependencyExtension
  5.     {
  6.         private static List<Type> GetTypes(Assembly assembly)
  7.         {
  8.             var result = assembly.GetTypes().Where(t => t != null && t.IsClass && !t.IsAbstract &&
  9.             t.CustomAttributes.Any(p => p.AttributeType == typeof(ExposedServiceAttribute))).ToList();
  10.             return result;
  11.         }
  12.         /// <summary>
  13.         /// 扩展IContainerRegistry接口的注册类型的功能
  14.         /// </summary>
  15.         /// <param name="container"></param>
  16.         /// <param name="assembly"></param>
  17.         public static void RegisterAssembly(this IContainerRegistry container, Assembly assembly)
  18.         {
  19.             var list = GetTypes(assembly);
  20.             foreach (var type in list)
  21.             {
  22.                 RegisterAssembly(container, type);
  23.             }
  24.         }
  25.         private static IEnumerable<ExposedServiceAttribute> GetExposedServices(Type type)
  26.         {
  27.             var typeInfo = type.GetTypeInfo();
  28.             return typeInfo.GetCustomAttributes<ExposedServiceAttribute>();
  29.         }
  30.         public static void RegisterAssembly(IContainerRegistry container, Type type)
  31.         {
  32.             var list = GetExposedServices(type).ToList();
  33.             foreach (var item in list)
  34.             {
  35.                 if (item.LiftTime == Lifetime.Singleton)
  36.                 {
  37.                     container.RegisterSingleton(type);//注册单例
  38.                 }
  39.                 foreach (var IType in item.Types)
  40.                 {
  41.                     if (item.LiftTime == Lifetime.Singleton)
  42.                     {
  43.                         container.RegisterSingleton(IType, type);//以接口注册单例
  44.                     }
  45.                     else if (item.LiftTime == Lifetime.Transient)
  46.                     {
  47.                         container.Register(IType, type);//以接口注册多例
  48.                     }
  49.                 }
  50.             }
  51.         }
  52.         /// <summary>
  53.         /// 初始化程序集中所有标注为ExposedServiceAttriubute特性的类,要求单例具自动加载AutoInitialize=true
  54.         /// </summary>
  55.         /// <param name="container"></param>
  56.         /// <param name="assembly"></param>
  57.         public static void InitializeAssembly(this IContainerProvider container, Assembly assembly)
  58.         {
  59.             var list = GetTypes(assembly);
  60.             foreach (var item in list)
  61.             {
  62.                 InitializeAssembly(container, item);
  63.             }
  64.         }
  65.         private static void InitializeAssembly(IContainerProvider container, Type type)
  66.         {
  67.             var list = GetExposedServices(type);
  68.             foreach (var item in list)
  69.             {
  70.                 if (item.LiftTime == Lifetime.Singleton && item.AutoInitialize)
  71.                 {
  72.                     container.Resolve(type);
  73.                 }
  74.             }
  75.         }
  76.     }
复制代码
 
图片模块IModule中配置,意思是在加载这个模块的时候会自动注册和初始化带有该模块中有ExposedServiceAttribute 特性的类
  1. [Module(ModuleName = ModuleName.ImageModuleProfile, OnDemand = true)]
  2.     public class ImageModuleProfile : IModule
  3.     {
  4.         public void OnInitialized(IContainerProvider containerProvider)
  5.         {
  6.             <strong>containerProvider.InitializeAssembly(Assembly.GetExecutingAssembly());</strong>
  7.             containerProvider.Resolve<IRegionManager>().RegisterViewWithRegion<ImageView>(ContentControlName.MainmoduleImagemoduleReginName);
  8.         }
  9.         public void RegisterTypes(IContainerRegistry containerRegistry)
  10.         {
  11.             <strong>containerRegistry.RegisterAssembly(Assembly.GetExecutingAssembly());</strong>
  12.             containerRegistry.RegisterForNavigation<ImageView, ImageViewModel>();
  13.         }
  14.     }
复制代码
 
使用:
  1. /// <summary>
  2.     /// 显示16位探测器图像的模型
  3.     /// </summary>
  4.     <strong>[ExposedService(Lifetime.Singleton, typeof(IDetectorDisplayModel))]
  5.     </strong>public class DetectorDisplayModel : IDetectorDisplayModel
  6.     {
  7.     }
复制代码
 
上面我们知道了如何利用特性的方式去注册服务,下面用ExposedServiceAttribute去注册Prism里面的功能
  1. <strong> [ExposedServiceAttribute(Lifetime.Singleton, AutoInitialize = true)]
  2.     </strong>public sealed class PrismProvider
  3.     {
  4.         public PrismProvider(
  5.             IContainerExtension container,
  6.             IRegionManager regionManager,
  7.             IDialogService dialogService,
  8.             IEventAggregator eventAggregator,
  9.             IModuleManager moduleManager)
  10.         {
  11.             LanguageManager = language;
  12.             Container = container;
  13.             RegionManager = regionManager;
  14.             DialogService = dialogService;
  15.             EventAggregator = eventAggregator;
  16.             ModuleManager = moduleManager;
  17.         }
  18.         /// <summary>
  19.         /// 容器
  20.         /// </summary>
  21.         public static IContainerExtension Container { get; private set; }
  22.         /// <summary>
  23.         /// 区域管理器接口
  24.         /// </summary>
  25.         public static IRegionManager RegionManager { get; private set; }
  26.         /// <summary>
  27.         /// 对话框管理器
  28.         /// </summary>
  29.         public static IDialogService DialogService { get; private set; }
  30.         /// <summary>
  31.         /// 事件聚合器
  32.         /// </summary>
  33.         public static IEventAggregator EventAggregator { get; private set; }
  34.         /// <summary>
  35.         /// 模块管理器
  36.         /// </summary>
  37.         public static IModuleManager ModuleManager { get; private set; }
  38.     }
复制代码
使用:
  1.             //第一步,加载模块
  2. <strong>            PrismProvider</strong>.ModuleManager.LoadModule(ModuleName.LoginModuleProfile);
  3.             //第二步,导航区域
  4.             <strong>PrismProvider</strong>.RegionManager.RequestNavigate(ContentControlName.MainWindowReginName, ViewNames.LoginView);
复制代码
 

来源:https://www.cnblogs.com/MingQiu/p/18005564
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具