现有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);
    }

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐