说说吧 发表于 2024-2-4 09:38:16

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

ModuleAttribute(按需延迟加载)
ModuleAttribute 是 Prism 框架中用于标识模块的属性。通过使用 ModuleAttribute,可以将模块与特定的模块目录进行关联,从而使 Prism 应用程序能够动态加载和初始化模块。
在使用 WPF ModuleAttribute 时,需要将该属性应用于模块类,并指定模块的模块目录路径。例如:
ModuleName:获取或设置模块的名称
OnDemand:获取或设置指示是否应按需加载模块的值。
StartupLoaded :获取或设置一个值,该值指示是否应在启动时加载模块

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 特性的类

    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>
    </strong>public class DetectorDisplayModel : IDetectorDisplayModel
    {

    } 
上面我们知道了如何利用特性的方式去注册服务,下面用ExposedServiceAttribute去注册Prism里面的功能
<strong>
    </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); 

来源:https://www.cnblogs.com/MingQiu/p/18005564
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 2.Prism框架ModuleAttribute、IOC扩展、功能注册