ModuleAttribute(按需延遲載入) ModuleAttribute 是 Prism 框架中用於標識模塊的屬性。通過使用 ModuleAttribute,可以將模塊與特定的模塊目錄進行關聯,從而使 Prism 應用程式能夠動態載入和初始化模塊。 在使用 WPF ModuleAttribut ...
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);