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

news2024/11/23 17:08:39

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>();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1422727.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

外汇天眼:纽约总检察长起诉花旗银行,指责其未能保护欺诈受害者

纽约总检察长莉蒂西亚詹姆斯今天起诉花旗银行&#xff0c;指责其未能保护并拒绝偿还欺诈受害者。该诉讼声称&#xff0c;花旗银行没有实施强有力的在线保护措施来阻止未经授权的账户劫持&#xff0c;误导账户持有人关于账户被黑客攻击并且资金被盗后的权利&#xff0c;并非法地…

uniapp多格式文件选择(APP,H5)

uniapp多格式文件选择&#xff08;APP&#xff0c;H5&#xff09; 背景实现代码实现运行结果注意事项 尾巴 背景 从手机选择文件进行上传是移动端很常见的需求&#xff0c;在原生开发时由于平台专一性很容易实现。但是用uniapp开发官方提供的API在APP平台只能选择图片和视频&a…

负载均衡下的webshell连接

一、环境配置 1.在Ubuntu上配置docker环境 我们选择用Xshell来将环境资源上传到Ubuntu虚拟机上&#xff08;比较简单&#xff09; 我们选择在root模式下进行环境配置&#xff0c;先将资源文件复制到root下&#xff08;如果你一开始就传输到root下就不用理会这个&#xff09; …

手把手教测试,全网内容最全最深-jmeter-Recording Controller(录制控制器)

5.1.6.14.Recording Controller(录制控制器) 第一步&#xff1a; 第二步&#xff1a;点击启动按钮&#xff0c;生成证书。证书在jmeter的bin目录下。 第三步&#xff1a;设置代理 第四步&#xff1a;抓取https包需要安装证书&#xff0c;在浏览器edge中安装 未完待续。。。 手…

Django4.2(DRF)+Vue3 读写分离项目部署上线

文章目录 1 前端2 后端2.1 修改 settings.py 文件关于静态文件2.2 关于用户上传的文件图片 3 Nginx4 镜像制作4.1 nginx4.3 Django镜像4.3.1 构建 5 docker-compose 文件内容 1 前端 进入前端项目的根目录&#xff0c;运行如下命令进行构建 npm run build构建完成后&#xff…

金田金业教你如何看懂国际黄金价格走势图

对于黄金投资者来说&#xff0c;看懂国际黄金价格走势图是至关重要的。通过观察走势图&#xff0c;可以了解金价的实时动态&#xff0c;预测未来的走势&#xff0c;从而做出相应的投资决策。本文将详细解析如何看懂国际黄金价格走势图。 一、国际黄金价格走势图的基本构成 国…

10s 内得到一个干净、开箱即用的 Linux 系统

安装 使用官方脚本安装我的服务器不行 官方脚本 mkdir instantbox && cd $_ bash <(curl -sSL https://raw.githubusercontent.com/instantbox/instantbox/master/init.sh) 下面是我的完整安装过程 mkdir /opt/instantbox cd /opt/instantbox 1.脚本文件 (这个没…

12.MySql服务

目录 1. 什么是数据库 1.1. 数据&#xff1a; 1.2. 数据库&#xff1a; 2. mysql概述 3. 版本及下载 4. yum仓库安装 4.1. 添加yum源 4.2. 安装 5. 本地RPM包安装 5.1. 使用迅雷下载集合包 5.2. 上传数据 5.3. 安装 6. 生产环境中使用通用二进制包安装 6.1. 作用…

如何应对Android面试官-> CoordinatorLayout详解,我用 Behavior 实现了手势跟随

前言 本章主要讲解下 CoordinatorLayout 的基础用法、工作原理和自定义Behavior 原理 使用很简单&#xff0c;百度上可以搜索下基础使用 协调者布局的功能 作为应用的顶层布局作为一个管理容器&#xff0c;管理与子 View 或者子 View 之间的交互处理子控件之间依赖下的交互处…

ChatGPT可与自定义GPTs一起使用,智能AI代理时代来啦!

1月31日凌晨&#xff0c;OpenAI在社交平台公布了一个超强新功能&#xff0c;可以在ChatGPT中输入“GPTs名字”的方法&#xff0c;调用多个自定义GPTs一起协同工作。 例如&#xff0c;我想开发一款社交APP&#xff0c;1&#xff09;可以先用专业分析GPTs做一下市场调研&#xf…

呼吸灯--FPGA

目录 1.breath_led.v 2.tb_breath_led.v 呼吸灯就是从完全熄灭到完全点亮&#xff0c;再从完全点亮到完全熄灭。具体就是通过控制PWM的占空比控制亮灭程度。 绘制PWM波的步骤就是&#xff0c;首先灯是在第一个时钟周期保持高电平熄灭状态&#xff0c;在第二个时钟周期保持1/1…

OpenGL 入门(三)— Textures(纹理)

文章目录 前言纹理环绕方式纹理过滤多级渐远纹理(Mipmap)加载与创建纹理stb_image.h库生成纹理 应用纹理顶点着色器片元着色器完整脚本 纹理单元 前言 纹理(Texture)。纹理是一个2D图片&#xff08;甚至也有1D和3D的纹理&#xff09;&#xff0c;它可以用来添加物体的细节。 你…

Visual Studio无法调试Unity的可能原因和解决办法

问题描述&#xff1a; 在unity和vs都安装了相关插件的情况下&#xff0c;vs在启动了“附加到Unity”后却并没有进入调试模式。 可能的原因及解决办法&#xff1a; 1、Unity未设置成调试模式 将Unity编辑器的右下角这个debug标志设置成debug模式: 设置后变成了&#xff1a; 注…

最小步数模型

AcWing 1107. 魔板 #include <bits/stdc.h> using namespace std;char g[2][4]; const int N 10; unordered_map<string, pair<char, string> > pre; unordered_map<string, int> d;void Set(string s) {for(int i0; i<4; i) g[0][i] s[i];for(in…

深入理解指针(1)

⽬录&#xff1a; 1. 内存和地址 2. 指针变量和地址 3. 指针变量类型的意义 4. const修饰指针 5. 指针运算 6. 野指针 7. 指针的使⽤和传址调⽤ 1. 内存和地址 1.1 内存 在讲内存和地址之前&#xff0c;我们想有个⽣活中的案例&#xff1a; 假设有⼀栋宿舍楼&#xff…

Nodejs基于Vue的物料物资生产销售制造执行系统

本系统具有的功能有&#xff1a; 后台&#xff1a; 1. 用户登录模块&#xff1a;账号密码的登录验证提示。 2. 基础数据模块&#xff1a;部门、员工、存货类型、计量单位、存货档案的增删改查。 3. 工程数据模块&#xff1a;工序、工艺路线、BOM管理的增删改查。 4. …

初探分布式链路追踪

本篇文章&#xff0c;主要介绍应用如何正确使用日志系统&#xff0c;帮助用户从依赖、输出、清理、问题排查、报警等各方面全面掌握。 可观测性 可观察性不单是一套理论框架&#xff0c;而且并不强制具体的技术规格。其核心在于鼓励团队内化可观察性的理念&#xff0c;并确保由…

聊聊java中的Eureka和Nacos

本文主要来自于黑马课程中 1.提供者与消费者 在服务调用关系中&#xff0c;会有两个不同的角色&#xff1a; 服务提供者&#xff1a;一次业务中&#xff0c;被其它微服务调用的服务。&#xff08;提供接口给其它微服务&#xff09; 服务消费者&#xff1a;一次业务中&#xff0…

JAVA和C#怎么开发SECS/GEM:recipe配方处理 S7F1、S7F19

recipe是什么内容呢&#xff1f; recipe是机台加工不同产品时的对应程式&#xff0c;指的是由制造工程师提前在机台上设置&#xff0c;并且EAP控制生产时会自动根据货的类型选择并控制机台按照制造工程师提前设置的方式进行加工。 recipe也称为配方&#xff0c;配方是怎么来的…

【springboot网页时装购物系统】

前言 &#x1f31e;博主介绍&#xff1a;✌全网粉丝15W,CSDN特邀作者、211毕业、高级全栈开发程序员、大厂多年工作经验、码云/掘金/华为云/阿里云/InfoQ/StackOverflow/github等平台优质作者、专注于Java、小程序技术领域和毕业项目实战&#xff0c;以及程序定制化开发、全栈…