什么是依赖注入

简介: 依赖注入的四种方法介绍。

废话

1. 为了提升自己的学习效率,通过写博客的方式从被动学习转化为一定程度的主动学习。

2.有一件每天都能坚持做的事情,可能更让人有或者的感觉?

在读《单元测试的艺术》的绪论的时候,有很多不懂的名词,就去查了一下,一些印象深刻的就记了些笔记。

Mostly I stopped using property setters and am mostly using constructor injection.

什么是依赖注入(Dependency Injection)

依赖注入是用来实现代码的松耦合的一种模式。如果一个对象需要进行另一个对象的创建,管理等过程,这样就会带来一种紧耦合。

例子:在一个游戏里面,我是一个武士,我有一把剑,我拿剑攻击。

///剑的类classSword{
publicvoidHit(stringtarget)
    {
Console.WriteLine("Chopped {0} clean in half", target);
    }
}
///武士的类,会用到那把剑,所以在里面新建了一个剑的实体classSamurai{
readonlySwordsword;
publicSamurai() 
    {
this.sword=newSword();
    }
publicvoidAttack(stringtarget)
    {
this.sword.Hit(target);
    }
}
///主函数,武士拿着剑去攻击别人classProgram{
publicstaticvoidMain() 
    {
varwarrior=newSamurai();
warrior.Attack("the evildoers");
    }
}


这里的武士就依赖于剑这个实体,是一种紧耦合。因为当我想给这武士换一把武器的时候。我需要去修改武士这个类的实现。

根据依赖倒置原则(DIP):高层模块不应该依赖于底层模块,二者都应该依赖于抽象。针对接口编程,不要针对实现编程。

这里Sword类就是底层模块,而我们以上用的方法就属于针对实现的编程。

那应该怎么修改呢?

///剑的抽象 是武器interfaceIWeapon{
voidHit(stringtarget);
}
///底层模块是剑,它应该依赖于武器这个抽象接口(继承,实现也是一种依赖关系)。classSword : IWeapon{
publicvoidHit(stringtarget) 
    {
Console.WriteLine("Chopped {0} clean in half", target);
    }
}


  1. 属性注入
///高层模块 是武士,他也应该依赖于武器这个抽象接口(组合也是一种依赖关系)///这就是一种属性注入(property injection),将武器作为武士的一种属性,通过特定函数来设置它classSamurai{
IWeaponweapon;
publicSamurai() { }
publicvoidSetWeapon(IWeaponweapon)
    {
this.weapon=weapon;
    }
publicvoidAttack(stringtarget) 
    {
this.weapon.Hit(target);
    }
}


  1. 构造注入
///将武器作为武士的构造器的参数传入classSamurai{
readonlyIWeaponweapon;
publicSamurai(IWeaponweapon) 
    {
this.weapon=weapon;
    }
publicvoidAttack(stringtarget) 
    {
this.weapon.Hit(target);
    }
}


  1. 方法注入
classSamurai{
publicvoidAttack(stringtarget, IWeaponweapon) 
    {
weapon.Hit(target);
    }
}

以上就是实现依赖注入的三种方式

  1. Constructor Injection
  2. Setter or property Injection
  3. Method Injection

还有第四种,我还没有学到。

  1. Service Locator Injection

还有这几种方式的优劣或者适用场景还有待学习,希望后续能够继续学习,继续分享。

参考:

https://softwareengineering.stackexchange.com/questions/177649/what-is-constructor-injection

https://www.c-sharpcorner.com/article/understanding-the-dependency-injection-using-constructor-property-and-method-in/

https://blog.csdn.net/qq_34760445/article/details/82931002

相关文章
|
存储 缓存 关系型数据库
PolarDB存储原理与实践
在阿里云开源的趋势下,PolarDB已经成功运用到很多企业案例中。
PolarDB存储原理与实践
|
缓存
学习OpenGL ES之绘制一个正方体
学习OpenGL ES之绘制一个正方体
学习OpenGL ES之绘制一个正方体
|
SQL Oracle 关系型数据库
能与PowerDesigner媲美的数据库建模工具PDMan
在设计数据库时,对现实世界进行分析、抽象、并从中找出内在联系,进而确定数据库的结构,这一过程就称为数据库建模。
590 0
能与PowerDesigner媲美的数据库建模工具PDMan
|
存储 缓存 编解码
手机连接电脑DCIM目录下文件夹和图片显示不全
学习手机连接电脑DCIM目录下文件夹和图片显示不全。
2139 0
|
Web App开发 数据安全/隐私保护 网络虚拟化
无影云电脑 - 我和我们的无影云
阿里推出的无影云电脑一些感受
1137 0
|
域名解析 网络协议 安全
绕过CDN寻找真实IP
正常情况下,通过cmd命令可以快速找到域名对应IP,最常见的命令如ping、nslookup。但很多站点出于用户体验和安全的角度,使用CDN加速,将域名解析到CDN,这时候就需要绕过CDN来查找真实IP。
|
消息中间件 运维 Java
在SpringBoot中实现异步事件驱动
在项目实际开发过程中,我们有很多这样的业务场景:一个事务中处理完一个业务逻辑后需要跟着处理另外一个业务逻辑,伪码大致如下:
1211 0
在SpringBoot中实现异步事件驱动
|
机器学习/深度学习 人工智能 自然语言处理
数字化转型时代,RPA+AI是打开人机协同的最佳方式
RPA+AI让自动化无处不在,自主认知的人机协同新时代已来 数字化转型时代,RPA+AI是打开人机协同的最佳方式
1359 0
数字化转型时代,RPA+AI是打开人机协同的最佳方式
|
机器学习/深度学习 Kubernetes 并行计算
如何通过ACK 纳管Nvidia A100 GPU实例,实现资源池化
### 介绍 在GTC 2020(5月14日)大会上英伟达新一代架构“Ampere”(安培)正式亮相。继数据中心Volta GPU推出三年后终于亮剑。Ampere以数据中心GPU A100的形式首次亮相,专为科学计算,云图形和数据分析而构建。 ![image.png](https://ata2-img.oss-cn-zhangjiakou.aliyuncs.com/614630bc
2079 0
如何通过ACK 纳管Nvidia A100 GPU实例,实现资源池化