WPF入门到跪下 第十一章 Prism(五)IOC的依赖注入

2024-01-31 17:04

本文主要是介绍WPF入门到跪下 第十一章 Prism(五)IOC的依赖注入,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

IOC的依赖注入

一、构造函数方式的依赖注入

以项目启动时MainWindowViewModel的依赖注入为例,默认情况下Prism框架的项目,在打开窗口时会自动匹配主窗口的视图模型类(PrismApplication启动),这里是MainWindowViewModel,匹配到之后Container自动创建MainWindowViewModel的实例,创建时会先检查MainWindowViewModel有没有无参构造函数,如果没有则会检查构造函数的参数类型,并在Container内部列表中寻找对应类型并创建参数对象,然后使用该参数对象来创建MainWindowViewModel。

设置好PrismApplication启动方式后,做以下处理实现IOC的构造函数依赖注入:

  • 创建业务接口及实现类

    public interface IDataAccessBase
    {DataTable GetDatas(string condition);
    }public class DataAccess : IDataAccessBase
    {public DataTable GetDatas(string condition){//做数据访问业务return null;}
    }
    
  • MainWindowViewModel的构造函数中传入所依赖的接口类型

    public class MainWindowViewModel
    {public MainWindowViewModel(IDataAccessBase dataAccess){var data = dataAccess.GetDatas("模拟一下");}
    }
    
  • 类型注册

    RegisterTypes函数中注册依赖类型

    public partial class App : PrismApplication
    {......protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.Register<IDataAccessBase, DataAccess>();}
    }
    

二、特性方式的依赖注入

注意,特性方式的注入时机要比构造函数方式的注入时机晚,因此如果需要在对象构造时使用依赖对象的话,最好用构造函数依赖注入的方式。

  • 类型注册

    RegisterTypes函数中注册依赖类型

    public partial class App : PrismApplication
    {......protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.Register<IDataAccessBase, DataAccess>();}
    }
    
  • 特性标注

    使用Prism.Unity命名空间下的Dependency标注属性成员,Prism框架会从IOC容器中寻找对应的类型并注入到属性中。如果在IOC容器中找不到,则会报错。

    public class MainWindowViewModel
    {[Dependency]public IDataAccessBase DataAccess{ get; set; }
    }
    

三、注册&注入已经存在的实例对象

有些情况下希望直接将一个已经存在的实例对象注册到IOC容器中;或者某个接口只返回接口类型的对象时,无法通过接口+实现类的方式注册到IOC容器中,只能先创建该实例对象,然后将实例对象注册到IOC容器中(例如Log4net)。这个时候可以使用IContainerRegistry对象的RegisterInstance方法。

1、注册

public partial class App : PrismApplication
{......protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.RegisterInstance(LogManager.GetLogger("Test"));//可以指定名称//containerRegistry.RegisterInstance(LogManager.GetLogger("Test"), TestLog);}
}

2、注入

注入方式,跟上文的一样,可以通过特性或者构造参数。

需要注意的是,如果指定了名称,就只能通过特性指定名称注入或者使用IUnityContainerIContainerExtension对象实例来获取了。

public MainWindow(ILog log)
{InitializeComponent();log.Error("错误", new Exception("发生了一个异常"));//错误log.Fatal("严重错误", new Exception("发生了一个致命错误"));//严重错误log.Info("信息"); //记录一般信息log.Debug("调试信息");//记录调试信息log.Warn("警告");//记录警告信息
}

IUnityContainer

一、获取注册信息

IUnityContainer接口的实例中存放了IOC容器中的注册信息,其中包括Prism框架默认注册的以及我们自己注册的。

以下为常用的三种注册方式后,IUnityContainer实例中存放注册信息的不同状态。

注册接口与类型,没有设置名称

public partial class App : PrismApplication
{......protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.Register<ITestClass, TestClass>();}
}

在这里插入图片描述

注册接口与类型,并设置名称

public partial class App : PrismApplication
{......protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.Register<ITestClass, TestClass>("TestClassName");}
}

在这里插入图片描述

直接注册类型

public partial class App : PrismApplication
{......protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.Register<TestClass>();}
}

在这里插入图片描述

不同的注册方式会导致注册信息的状态有所不同,其中导航、视图、类型的注册根据不同情况也有所不同,在实际开发过程中可以先监控一下IUnityContainer实例中的注册信息再根据实际情况来使用。

需要注意的是,如果在注册过程中设置了name属性,那么在向容器中获取对象时,也要使用对应的name来获取,如果还使用类名来获取,会直接报错。

二、从容器中获取对象

除了能在IUnityContainer实例中获取到IOC容器的注册信息外,还能通过实例方法Resolve<T>()从容器中获取指定的依赖对象。
此外,从IContainerProvider实例的Resolve<T>()方法中也可以从容器中获取指定的依赖对象。

public partial class App : PrismApplication
{......protected override void RegisterTypes(IContainerRegistry containerRegistry){containerRegistry.RegisterSingleton<ITestClass, TestClass>();}
}
public class MainWindowViewModel
{public MainWindowViewModel(IUnityContainer unityContainer,  IContainerProvider containerProvider){var a = unityContainer.Resolve<ITestClass>();var b = containerProvider.Resolve<ITestClass>();var result = a == b;	//true}
}

三、实例-Region中删除指定视图

public class FileUploadViewModel:BindableBase
{//页签关闭命令public ICommand CloseCommand { get; set; }public FileUploadViewModel(IRegionManager regionManager, IUnityContainer unityContainer){CloseCommand = new DelegateCommand<string>(uri =>{//从IUnityContainer 实例中获取指定的注册信息对象var obj = unityContainer.Registrations.Where(r => r.Name == uri || r.MappedToType == Type.GetType("FileUploadView")).FirstOrDefault();var name = obj?.MappedToType.Name;if (!string.IsNullOrEmpty(name)){var region = regionManager.Regions["MainViewRegion"];var view = region.Views.Where(v=> v.GetType().Name == name).FirstOrDefault();if (view != null)region.Remove(view);}});}
}

IContainerExtension

Prism的IOC容器中默认注册的还有IContainerExtension接口,该接口实现了IContainerProviderIContainerRegistry接口,因此其实现类的实例对象同时具有注册和从容器中获取对象的功能,如果希望在App类中的RegisterTypes方法之外的地方向容器注册的话,可以通过IContainerExtension的实例对象来完成。

public class MainWindowViewModel
{public MainWindowViewModel(IUnityContainer unityContainer,  IContainerExtension containerProvider){containerProvider.Register<TestClass>();var test = containerProvider.Resolve<TestClass>();}
}

这篇关于WPF入门到跪下 第十一章 Prism(五)IOC的依赖注入的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/664455

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

每天认识几个maven依赖(ActiveMQ+activemq-jaxb+activesoap+activespace+adarwin)

八、ActiveMQ 1、是什么? ActiveMQ 是一个开源的消息中间件(Message Broker),由 Apache 软件基金会开发和维护。它实现了 Java 消息服务(Java Message Service, JMS)规范,并支持多种消息传递协议,包括 AMQP、MQTT 和 OpenWire 等。 2、有什么用? 可靠性:ActiveMQ 提供了消息持久性和事务支持,确保消

数论入门整理(updating)

一、gcd lcm 基础中的基础,一般用来处理计算第一步什么的,分数化简之类。 LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } <pre name="code" class="cpp">LL lcm(LL a, LL b){LL c = gcd(a, b);return a / c * b;} 例题:

Java 创建图形用户界面(GUI)入门指南(Swing库 JFrame 类)概述

概述 基本概念 Java Swing 的架构 Java Swing 是一个为 Java 设计的 GUI 工具包,是 JAVA 基础类的一部分,基于 Java AWT 构建,提供了一系列轻量级、可定制的图形用户界面(GUI)组件。 与 AWT 相比,Swing 提供了许多比 AWT 更好的屏幕显示元素,更加灵活和可定制,具有更好的跨平台性能。 组件和容器 Java Swing 提供了许多

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联

poj 2104 and hdu 2665 划分树模板入门题

题意: 给一个数组n(1e5)个数,给一个范围(fr, to, k),求这个范围中第k大的数。 解析: 划分树入门。 bing神的模板。 坑爹的地方是把-l 看成了-1........ 一直re。 代码: poj 2104: #include <iostream>#include <cstdio>#include <cstdlib>#include <al

MySQL-CRUD入门1

文章目录 认识配置文件client节点mysql节点mysqld节点 数据的添加(Create)添加一行数据添加多行数据两种添加数据的效率对比 数据的查询(Retrieve)全列查询指定列查询查询中带有表达式关于字面量关于as重命名 临时表引入distinct去重order by 排序关于NULL 认识配置文件 在我们的MySQL服务安装好了之后, 会有一个配置文件, 也就

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip

深入理解数据库的 4NF:多值依赖与消除数据异常

在数据库设计中, "范式" 是一个常常被提到的重要概念。许多初学者在学习数据库设计时,经常听到第一范式(1NF)、第二范式(2NF)、第三范式(3NF)以及 BCNF(Boyce-Codd范式)。这些范式都旨在通过消除数据冗余和异常来优化数据库结构。然而,当我们谈到 4NF(第四范式)时,事情变得更加复杂。本文将带你深入了解 多值依赖 和 4NF,帮助你在数据库设计中消除更高级别的异常。 什么是

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显