Prism注册和获取实例(IContainerRegistry和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 的对话框服务中使用,用于弹出对话框窗口。

通过 RegisterDialogWindowRegisterDialog,你可以将一个对话框窗口类注册到容器中,然后使用 IDialogService 来启动该对话框。

注册对话框

public class MyModule : IModule
{
    public void RegisterTypes(IContainerRegistry containerRegistry)
    {
        // 注册对话框 MyDialog
        containerRegistry.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));

对话框窗口实现

对话框通常是一个 WindowUserControlIDialog 接口用于处理对话框的显示和返回结果。

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");
    }
}
主要区别
特性RegisterDialogRegisterDialogWindow
注册类型注册任意实现了 IDialog 接口的视图(如 UserControlWindow)。注册继承自 Window 的对话框视图。
接口要求需要实现 IDialog 接口,提供更多自定义功能(如接收和传递参数)。不需要实现 IDialog 接口,适用于简单的窗口类型。
灵活性更灵活,适合需要自定义行为的对话框。更简化,适合快速注册和使用基本的 Window 作为对话框。
适用场景适用于复杂的对话框交互,涉及传递和处理参数等。适用于简单的对话框,没有复杂交互需求。

Register注册类型

有以下两种情况:

//1、注册MyService类型到容器中
containerRegistry.Register<MyService>();
//2、将 IService 接口类型和 MyService 具体类型进行捆绑注册
containerRegistry.Register<IService, MyService>();
  1. 使用 Register<MyService>() 是直接注册类本身,需要 MyService 类型时,容器会提供它的实例。适合直接使用具体类的场景,不涉及抽象或接口。

  2. 使用 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"));
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值