Prism IoC 依赖注入

发布时间 2023-08-18 11:12:45作者: WebEnh

现有2个项目,SinglePageApp是基于Prism创建的WPF项目,框架使用的是Prism.DryIoc,SinglePageApp.Services是C#类库,包含多种服务,下面通过使用Prism中的依赖注入方式,将自定义的服务注册到SinglePageApp项目中。

 

1. 认识 Prism 中的依赖注入
Prism项目中的 App 继承于 PrismApplication ,必须要重写 CreateShell() 和 RegisterTypes() 方法,其中 RegisterTypes()用于依赖注入容器,该函数使用 IContainerRegistry 类型的对象将用户自定义的对象注入容器。

在Prism源码中,已经提前向IOC容器注入了如下内容:

 


protected virtual void RegisterRequiredTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IApplicationProvider, ApplicationProvider>();
containerRegistry.RegisterSingleton<IApplicationStore, ApplicationStore>();
containerRegistry.RegisterSingleton<IEventAggregator, EventAggregator>();
containerRegistry.RegisterSingleton<IKeyboardMapper, KeyboardMapper>();
containerRegistry.RegisterSingleton<IPageDialogService, PageDialogService>();
containerRegistry.RegisterSingleton<IDialogService, DialogService>();
containerRegistry.RegisterSingleton<IDeviceService, DeviceService>();
containerRegistry.RegisterSingleton<IPageBehaviorFactory, PageBehaviorFactory>();
containerRegistry.RegisterSingleton<IModuleCatalog, ModuleCatalog>();
containerRegistry.RegisterSingleton<IModuleManager, ModuleManager>();
containerRegistry.RegisterSingleton<IModuleInitializer, ModuleInitializer>();
containerRegistry.RegisterScoped<INavigationService, PageNavigationService>();
containerRegistry.Register<INavigationService, PageNavigationService>(NavigationServiceName);
}
有了这些内容,就可以在窗体里通过构造函数直接注入对象,如

public partial class MainWindow : Window
{
private IContainerExtension _container;
private IModuleManager _moudleManager;
private IRegionManager _regionManager;
private IEventAggregator _eventAggregator;

public MainWindow(IContainerExtension container, IModuleManager moudleManager,IRegionManager regionManager, IEventAggregator eventAggregator)
{
InitializeComponent();
this._container = container;
this._moudleManager = moudleManager;
this._regionManager = regionManager;
this._eventAggregator = eventAggregator;
}
}
这样就可以使用容器中注入的对象。

2. 通过 App.xaml.cs 中的 RegisterTypes() 函数接口将对象注入容器
如果自定义了第三方对象,如 SinglePageApp.Services 中有两个自定义的服务 MD5Provider 和 Password,想将这2个对象注入Prism中的容器,供前端界面使用,可以重写 App.xaml.cs 中的 RegisterTypes() 函数接口,通过 IContainerRegistry 类型的对象将自定义的服务注入 IOC 容器。这里以MD5Provider 注入为例。

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<MD5Provider>();
}
然后在你要用它的地方,如 IndexViewModel.cs 中,通过构造函数从 IOC 容器里将对象解析出来。

private readonly MD5Provider _provider1;
private readonly MD5Provider _provider2;
private readonly IContainerExtension _container;

public IndexViewModel(IContainerExtension container)
{
_container = container;
_provider1 = container.Resolve<MD5Provider>();
_provider2 = container.Resolve<MD5Provider>();
}
注意:使用 Register 方法注入,每次解析都会创建一个新的对象,所以 _provider1 == _provider2 是不成立的;如果在RegisterTypes()中没有将对象 MD5Provider 注入容器,在构造函数中解析的时候也会自动创建一个MD5Provider 对象。

依赖注入的几种方法:

Register:每一次解析都会创建一个实例
RegisterSingleton :整个应用程序生命周期以内只创建一个实例(单例)
RegisterScoped :在同一个Scope内只初始化一个实例
使用 RegisterScoped 注入,则 _provider1 == _provider2 成立,因为它们2个对象处于同一个Scope。

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterScoped<MD5Provider>();
}
使用 RegisterSingleton 注入,则 _provider1 == _provider2 成立,因为 MD5Provider 是单例,整个应用程序只有一个它的实例。

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<MD5Provider>();
}
在构造函数中注入对象时,也可以直接传入对象,不用手动调用 Resolve 方法进行解析,如

private readonly MD5Provider _provider1;
private readonly MD5Provider _provider2;

public IndexViewModel(MD5Provider provider1, MD5Provider provider2)
{
_provider1 = provider1;
_provider2 = provider2;
}
3. 以模块的方式注入容器
为 SinglePageApp.Services 项目建立一个模块描述文件 ServicesProfile.cs ,继承接口 Imodule ,在模块描述文件中进行依赖注入。(该方法要在SinglePageApp.Services 项目安装 Prism.DryIoc)

public class ServicesProfile : IModule
{
public void OnInitialized(IContainerProvider containerProvider)
{

}

public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<MD5Provider>();
containerRegistry.Register<Password>();
}
}
然后在 App.xaml.cs 中重写 ConfigureModuleCatalog 函数加载模块,实现模块的整体注入。

protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
moduleCatalog.AddModule<ServicesProfile>();

base.ConfigureModuleCatalog(moduleCatalog);
}

Jiestriker
关注

————————————————
版权声明:本文为CSDN博主「Jiestriker」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_38318941/article/details/124062641