首页 > 其他分享 >依赖注入和依赖注入容器

依赖注入和依赖注入容器

时间:2022-08-31 09:03:16浏览次数:84  
标签:容器 依赖 Car 实例 我们 注入

依赖注入和依赖注入容器

依赖注入 是一种有助于避免模块中的硬编码依赖性的模式,使调用者有权更改它们并在他们想要的地方提供自己的。让我们通过一个例子来弄清楚它需要什么:

让我们看一下这个例子,Car 类需要一个 Tires 类的实例。我们可以说汽车依赖于轮胎。正如我们所看到的,这个例子是有效的,轮胎字段在 Car 构造函数中由轮胎类的实例成功初始化。但是,这种方法会导致 问题 .要查看它们,让我们更改轮胎类的实现(例如,添加一个构造函数参数)

我们看到,现在为了正确获取 Car 中的 Tires 类实例,我们需要对 Car 类进行更改。
在更改Tires类时,我们必须找到所有在其他类中使用它的地方并进行更改,非常不方便。
此外,现在要获取 Car 类的实例,我们需要传递的不是 3 个而是 4 个参数。如果你想象 Car 类也可以用在更高级别的模块中——那么一个类的变化可能会导致一系列类似雪崩的变化。
测试 Car 也有困难,不可能替换 Tires 实现,因为它在使用的地方直接硬编码。
事实证明,一个类依赖于另一个类的实现,这违反了 SOLID 原则之一——依赖倒置原则 (DIP)。高级模块不应该依赖于低级模块;两种类型都应该依赖于抽象。

为了解决这个问题,让我们将必要的依赖传递给 Car 类的构造函数的参数。

我们已经传递了一个依赖项(Tires 类的实例)作为 Car 类的构造函数的参数,现在 Car 类的实现不依赖于 Tires。
这种模式称为 依赖注入 .

现在让我们想想,这种方法是否足够?
尽管它很简单,但在大型应用程序中这种方法可能无法扩展。想象一个模块可能有很多依赖,它们可能有自己的依赖。
然后检查依赖关系,匹配它们的类型,正确地并以正确的顺序转移依赖关系成为一项不平凡的任务,随着项目变得更加复杂,其复杂性也会增加。
此外,如果其中一个依赖项发生了变化,那么无论在何处传输,都需要替换它。
考虑这个例子:

要获取 Car 类的实例,我们需要手动创建其所有依赖项的实例,而这些依赖项又具有依赖项。

现在假设我们在应用程序的许多地方创建 Car 实例,我们需要更改其中一个依赖项,然后我们必须找到所有这些地方并手动修复依赖项。
如果某个实体为我们做这件事,创建所有依赖项的实例并注入它们,那就太好了。
为了解决这个问题,我们将使用控制反转 (IoC) 模式——其本质是开发人员将部分权力用于购买外部实体——函数、库或框架。关于 DI,IoC 是我们在描述类时只指定依赖关系。并且这些依赖项的实例的创建由一些外部代码控制,例如, 依赖注入容器 (DIС) 初始化主类的实例时。
让我们创建一个最简单的依赖注入容器:

让我们弄清楚这个依赖注入容器是如何工作的。
'的概念 依赖关系 ' 在这里使用 - 这些是 班级 需要创建其实例,并且 ' 论据 ' - 是 类、对象或原语的实例, 我们作为参数传递给构造函数。
依赖注入容器将依赖项和参数存储在单独的对象中,其中键是构造函数参数的名称,值 this 是类(用于依赖项)和对象或原语(用于参数)。首先,使用 registerDependency 方法,我们传递给
DIC 所有依赖项并使用 setArgument 方法传递所有参数。然后我们调用 get('car') 方法(在我们的例子中,Car 类具有键 'car')。接下来调用getInstance(Car)方法,得到
Car 类的构造函数的参数名称,并且对于每个参数,再次递归调用 get(parametrName) 方法。如果参数名称与参数匹配,则该方法返回此参数的值。如果参数名称与依赖项匹配,则再次调用该方法 getInstance(dependency) 创建一个依赖项实例并将其作为参数传递。

让我们创建一个依赖注入容器实例并在其中注册所有需要实例化的依赖项,它们将永久存储在容器中并且不需要修改。

现在,在获取 Car 实例的代码中的任何地方,我们将必要的参数传递给依赖注入容器并调用 get() 方法,指定我们要创建的类的实例。

结果将与手动传输依赖项时相同。要获得另一辆车,您只需重置参数并将新参数传递给 DIC,依赖关系保持不变。

现在让我们更改依赖关系,而不是我们使用 Driver 类的 Person 类。

用DIC很容易做到这一点,更换就足够了

dic.register Dependency('person', Person);
dic.register Dependency('person', Driver);

并且在应用程序中创建的所有汽车都将自动接收新的依赖项。

当然,这个依赖注入容器并没有解决依赖注入的所有问题,只是展示了基本原理。

我希望这篇文章对你有用。感谢关注!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/2966/49173108

标签:容器,依赖,Car,实例,我们,注入
From: https://www.cnblogs.com/amboke/p/16641720.html

相关文章

  • 安卓集成新版推送SDK与旧版本账号SDK发生依赖冲突,如何解决?
    ​ 1、问题描述一开始项目中是集成了华为登录SDK,如下图所示:​现在想要接入华为推送SDK,如下图所示:​结果集成之后出现了依赖冲突的问题,报错如下图中所示:​ 2、问......
  • 容器类型转换
    1、tuple()将某个序列转换成元组2、list()将某个序列转换成列表3.set()将某个列表转换成集合注意:集合可以快速完成列表去重集合不支持下标list1=[10,20......
  • 搭建ELK及kafka日志收集环境之容器内置(filebeat)日志收集
    架构图1、构建tomcat镜像1.1、基础环境准备 1.2、build-command脚本与Dockefile准备[root@easzlab-images-02tomcat-base]#catbuild-command.sh#!/bin/bashT......
  • .NET 使用自带 DI 批量注入服务(Service)和 后台服务(BackgroundService)
    在默认的.net项目中如果我们注入一个服务或者后台服务,常规的做法如下 注册后台服务builder.Services.AddHostedService<ClearLogTask>();针对继承自接口的服务......
  • .NET 纯原生实现 Cron 定时任务执行,未依赖第三方组件
    常用的定时任务组件有Quartz.Net和Hangfire两种,这两种是使用人数比较多的定时任务组件,个人以前也是使用的Hangfire,慢慢的发现自己想要的其实只是一个能够根据Cron......
  • Maven找不到依赖终极解决方案
    离线网络环境中拷贝maven仓库到离线机器,使用maven加载项目,maven编译jar包找不到或者提示jar包信息不可用,现提供以下本人解决的方式,亲测可用基础解决方案常规idea的maven......
  • gradle多模块项目打包依赖拆分
    一、目录结构.├──boogle-common│  ├──build.gradle.kts│  └──src├──boogle-core│  ├──build.gradle.kts│  └──src├──......
  • yarn,npm安装依赖踩坑
    1、当删除lock文件后npminstall报依赖错误,运行npminstall--legacy-peer-deps2、install时node-sass报错,node-sass:Commandfailednodenode-sasssass-loader是完......
  • Docker容器数据卷
    什么是容器数据卷如果数据都在容器中,如果容器一删除,那么数据就会丢失。我们希望数据存储在本地。容器之间可以有一个数据共享的技术,Docker容器产生的数据,同步到本地,这就......
  • docker --link容器互联
    目录一.系统环境二.docker容器互联概述2.1docker容器互联的三种方式2.2docker--link使用注意事项2.3docker--link原理三.docker容器互联3.1通过容器IP地址进行通信3.......