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

  • 2.Prism框架ModuleAttribute、IOC扩展、功能注册已关闭评论
  • 120 次浏览
  • A+
所属分类:.NET技术
摘要

ModuleAttribute(按需延迟加载) ModuleAttribute 是 Prism 框架中用于标识模块的属性。通过使用 ModuleAttribute,可以将模块与特定的模块目录进行关联,从而使 Prism 应用程序能够动态加载和初始化模块。

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>     [AttributeUsage(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:自定义特性的对象,可以是类、方法、属性等对象(默认值是 AttributeTargets.All)
AllowMultiple:是否允许被多次使用(默认值为false:单用的)
Inherited:是否可被派生类继承(默认值为false:不能)


依赖注入扩展类:
加载模块时,实例化标注为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)         {             containerProvider.InitializeAssembly(Assembly.GetExecutingAssembly());             containerProvider.Resolve<IRegionManager>().RegisterViewWithRegion<ImageView>(ContentControlName.MainmoduleImagemoduleReginName);         }          public void RegisterTypes(IContainerRegistry containerRegistry)         {             containerRegistry.RegisterAssembly(Assembly.GetExecutingAssembly());             containerRegistry.RegisterForNavigation<ImageView, ImageViewModel>();         }     }

 

使用:

/// <summary>     /// 显示16位探测器图像的模型     /// </summary>     [ExposedService(Lifetime.Singleton, typeof(IDetectorDisplayModel))]     public class DetectorDisplayModel : IDetectorDisplayModel     {      }

 

上面我们知道了如何利用特性的方式去注册服务,下面用ExposedServiceAttribute去注册Prism里面的功能

 [ExposedServiceAttribute(Lifetime.Singleton, AutoInitialize = true)]     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; }      }

使用:

            //第一步,加载模块             PrismProvider.ModuleManager.LoadModule(ModuleName.LoginModuleProfile);             //第二步,导航区域             PrismProvider.RegionManager.RequestNavigate(ContentControlName.MainWindowReginName, ViewNames.LoginView);