Prism注册和获取实例
- 注册和获取实例(IContainerRegistry和IContainerProvider)
- IContainerRegistry的使用
- RegisterInstance注册实例
- RegisterSingleton注册单例服务
- RegisterDialogWindow和RegisterDialog注册对话框
- 主要区别
- Register注册类型
- RegisterForNavigation
- RegisterScoped注册作用域实例
- IContainerProvider的使用
注册和获取实例(IContainerRegistry和IContainerProvider)
IContainerRegistry:Prism框架中,用于注册和配置应用程序中的依赖注入(DI)容器的接口。我们通过它想容器中注册类型或实例。
IContainerProvider:Prism框架中,依赖注入(DI)容器的提供者。作用是从容器中解析和获取已注册的服务实例。基本上,IContainerProvider
就是我们与依赖注入容器交互的接口。
IContainerRegistry的使用
应用场景:
- 注册服务:在应用启动的时候使用
RegisterTypes
方法来注册各种服务和依赖项,确保它们能够在整个应用程序中被访问和注入。 - 视图模型和视图的导航:Prism 中的导航(Navigation)功能依赖于容器注册。
- 构建松耦合应用:通过将视图、视图模型、服务等组件注入到 DI 容器中,你可以使得应用程序更加松耦合,易于测试和扩展。
在Prism的应用程序初始化过程中RegisterTypes示例如下:
public partial class App : PrismApplication
{protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.RegisterInstance(typeof(IClientConfig), ClientConfig.Instance);containerRegistry.RegisterInstance(typeof(UserInfo), UserInfo);containerRegistry.RegisterDialogWindow<UDialog>("UDialog");containerRegistry.RegisterSingleton<IAppDialogService, AppDialogService>();containerRegistry.RegisterSingleton<IPreviewPptService, PreviewPptService>();containerRegistry.RegisterDialog<ConfirmDialog, ConfirmDialogViewModel>();containerRegistry.Register<PreviewPptUcViewModel>();}
}
RegisterInstance注册实例
注册一个现有的实例,所有请求都返回同一个实例。该生命周期与容器的生命周期相同,在整个应用程序中始终是同一个实例,直到容器被释放或程序终止。
如上文中的程序,如下两句:
containerRegistry.RegisterInstance(typeof(IClientConfig), ClientConfig.Instance);
containerRegistry.RegisterInstance(typeof(UserInfo), UserInfo);
RegisterSingleton注册单例服务
在容器中注册一个单例服务,在整个应用程序生命周期内只创建一个实例,并且这个实例在所有需要它的地方共享。
注册的时候没有实例对象(与RegisterInstance的区别)。从容器中获取实例时,只在第一次获取实例时会创建一次,之后所有请求该服务的地方都返回同一个实例。
containerRegistry.RegisterSingleton<IAppDialogService, AppDialogService>();
RegisterDialogWindow和RegisterDialog注册对话框
Prism框架中的扩展方法,用于注册自定义对话框窗口,使得它可以通过依赖注入机制在应用程序中使用。通常在 Prism 的对话框服务中使用,用于弹出对话框窗口。
通过 RegisterDialogWindow
或RegisterDialog
,你可以将一个对话框窗口类注册到容器中,然后使用 IDialogService
来启动该对话框。
注册对话框:
public class MyModule : IModule
{public void RegisterTypes(IContainerRegistry containerRegistry){// 注册对话框 MyDialogcontainerRegistry.RegisterDialog<MyDialog>();//containerRegistry.RegisterDialogWindow<MyDialog>();}
}
在ViewModel中打开对话框:
public class MainViewModel
{private readonly IDialogService _dialogService;public MainViewModel(IDialogService dialogService){_dialogService = dialogService;}// 打开默认的对话框public void ShowDialog(){_dialogService.ShowDialog(nameof(MyDialog));}//打开有参数的对话框public void ShowDialogWithParameters(){var parameters = new DialogParameters{{ "Title", "Confirmation" },{ "Message", "Are you sure you want to delete this item?" }};_dialogService.ShowDialog(nameof(MyDialog), parameters);}
}
ViewModel中关闭对话框
// 关闭当前打开的对话框
_dialogService.CloseDialog("MyDialog", new DialogResult(ButtonResult.OK));
对话框窗口实现
对话框通常是一个 Window
或 UserControl
。IDialog
接口用于处理对话框的显示和返回结果。
public partial class MyDialog : Window, IDialog
{private readonly IEventAggregator _eventAggregator;public MyDialog(IEventAggregator eventAggregator){InitializeComponent();_eventAggregator = eventAggregator;}public void OnDialogClosed(){// 处理对话框关闭逻辑}public void OnDialogOpened(IDialogParameters parameters){// 处理对话框打开时的逻辑,获取传递的参数var title = parameters.GetValue<string>("Title");var message = parameters.GetValue<string>("Message");}
}
主要区别
特性 | RegisterDialog | RegisterDialogWindow |
---|---|---|
注册类型 | 注册任意实现了 IDialog 接口的视图(如 UserControl 或 Window )。 | 注册继承自 Window 的对话框视图。 |
接口要求 | 需要实现 IDialog 接口,提供更多自定义功能(如接收和传递参数)。 | 不需要实现 IDialog 接口,适用于简单的窗口类型。 |
灵活性 | 更灵活,适合需要自定义行为的对话框。 | 更简化,适合快速注册和使用基本的 Window 作为对话框。 |
适用场景 | 适用于复杂的对话框交互,涉及传递和处理参数等。 | 适用于简单的对话框,没有复杂交互需求。 |
Register注册类型
有以下两种情况:
//1、注册MyService类型到容器中
containerRegistry.Register<MyService>();
//2、将 IService 接口类型和 MyService 具体类型进行捆绑注册
containerRegistry.Register<IService, MyService>();
-
使用
Register<MyService>()
是直接注册类本身,需要MyService
类型时,容器会提供它的实例。适合直接使用具体类的场景,不涉及抽象或接口。 -
使用
Register<IService, MyService>()
是为了注册接口和实现的关联,需要IService
类型的地方(如通过依赖注入),容器会提供MyService
类的实例。适合解耦和灵活切换实现。
当多个具体类实现了IService接口,要使用依赖注入(DI)容器时,可以使用命名注册
// 使用命名注册
containerRegistry.Register<IService, MyService1>("Service1");
containerRegistry.Register<IService, MyService2>("Service2");// 通过标记明获取实现
var service1 = container.Resolve<IService>("Service1");
var service2 = container.Resolve<IService>("Service2");
RegisterForNavigation
containerRegistry.RegisterForNavigation<MyView, MyViewModel>();
RegisterScoped注册作用域实例
注册一个作用域内的实例,每个作用域内共享实例,跨作用域不共享。
通常是:每次请求都创建一个新的实例,但每个请求内只有一个实例,如在Web应用中,作用域通常指的是一个HTTP请求。服务的生命周期在特定的作用域内,每次进入新作用域时会创建一个新的实例,而同一作用域内的多个请求会共享该实例。
container.RegisterScoped<IMyService, MyService>();
IContainerProvider的使用
作用是从容器中解析和获取已注册的服务实例。基本上,IContainerProvider
是你与依赖注入容器交互的接口。
主要通过:
- Resolve(Type type)、**Resolve<T>() **两个方法来解析出容器中的实例;
- IsRegistered(Type type)、IsRegistered<T>() 可以检查某个类型是否注册;
//解析具体类
var myService = containerProvider.Resolve<MyService>();//解析已注册的接口或抽象类型
containerRegistry.Register<IService, MyService>();
var service = containerProvider.Resolve<IService>();//解析带有条件的类型实例
// 使用命名注册
containerRegistry.Register<IService, MyService1>("Service1");
containerRegistry.Register<IService, MyService2>("Service2");
// 通过标记明获取实现
var service1 = container.Resolve<IService>("Service1");
var service2 = container.Resolve<IService>("Service2");//解析带有显式参数的实例(即解析时获取的对象需要传参初始化)
var service = containerProvider.Resolve<MyService>(new Parameter("param1", "value1"));