希望给你3-5分钟的碎片化学习,可能是坐地铁、等公交,积少成多,水滴石穿,谢谢关注。

从UML来理解依赖

1.1什么是依赖

我们先看下图

可以简单理解,一个HomeController类使用到了DBContext类,而这种关系是有偶然性,临时性,弱关系的,但是DBContext的变化会影响到HomeController

1.2显示依赖和隐式依赖

先看显示依赖代码:

显示依赖通过构造函数,很清楚的描述了HomeController类都依赖了哪些对象,这样就可以很好的管理这些依赖。而隐式依赖的缺点刚好就是显示依赖的优点。我们看下面的隐式依赖:

如果一个类有上千行代码,到处都充斥着该类型的代码,这些代码就像隐藏的病毒一样,无处不在,可以想象后续的变化和修改是多么的恐怖。

1.3依赖倒置

依赖倒置的概念其实很简单,一句话就讲完了:我们要依赖抽象,而不依赖具体实现。什么是抽象?比如接口,抽象类就是。

依赖抽象的目的是什么?封装变化!因为所有实现接口的实现都可以互相替换。

如上图所示,当数据库DapperUserRepository切换到EfUserRepository,对HomeController类可以无需任何修改,就可以平滑切换过去。反之,则更改的面就会非常大。

再看下面的代码,OrderController依赖接口IUserRepository就是依赖倒置的表现。

从单元测试来理解

也许你会说,我的变化没有那么频繁,不需要那么麻烦。那么你是否考虑过,有可能自己的代码需要进行单元测试?如果存在这种可能,那么依赖注入是你必须要做的事。

2.1控制反转

我们再看下面这个代码的问题

虽然OrderController依赖的是接口IUserRepository,满足依赖倒置原则,但是构造函数却依赖的是具体实现类UserRepository,这种做法属于硬编码,仍然无法满足未来变化带来的修改,怎么办?接下来我们来讲控制反转这个相对难以理解的概念。

先说反转,到底反转的是什么?我们知道OrderController依赖的对象UserRepository是在构造函数内的生成的。如何能够把该对象的生成交给外部去决定生成呢?可以的!这种转移对象生成的方式就是控制反转。

简而言之,反转的是控制权,即依赖对象生成的控制权。是自己决定生成还是交由别人去决定生成。

所以上面的代码,修改如下:

以上的代码才达到真正的控制反转,UserRepository对象的生成完全交由外部进行控制,交给变化去控制。

这样有什么好处呢?交给外部生成的最大好处是想要生成什么对象可以自由控制,这样还是为了将来对象生成的可替换,比如数据库访问对象的变更;单元测试的实现类替换等等。

这里借用大内老A一句话做为总结,所谓控制反转就是将对应流程的控制权转移到框架里。

2.2单元测试

有了上面的控制反转,我们的单元测试就方面很多了。

我们可以看到,在数据库无法连接的时候,我们可以使用MemoryUserRepository进行替换单元测试,非常方便。

我是IT人张飞洪,入行10年有余,人不堪其忧,吾不改其乐,谢谢您关注

3.1依赖注入「深入浅出ASP.NET Core系列」的更多相关文章

  1. 1.1专题介绍「深入浅出ASP.NET Core系列」

    大家好,我是IT人张飞洪,专注于.NET平台十年有余. 工作之余喜欢阅读和写作,学习的内容包括数据结构/算法.网络技术.Linux系统原理.数据库技术原理,设计模式.前沿架构.微服务.容器技术等等…… ...

  2. 2.3Options建立配置和实体的映射「深入浅出ASP.NET Core系列」

    希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,谢谢关注. Startup.cs中创建MVC中间件 关键代码:services.AddMvc();app.UseMvcWith ...

  3. 2.4配置的热更新「深入浅出ASP.NET Core系列」

    希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,谢谢关注. 大家知道通常我们修改网站的配置文件比如,webconfig的时候,网站需要重启才能读取到最新的修改,所谓热更新就是 ...

  4. 目录导航「深入浅出ASP.NET Core系列」

    希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,谢谢关注. 入门篇 引子 1.1专题介绍 1.2环境安装 1.3创建项目 1.4部署到IIS 1.5准备CentOS和Ngin ...

  5. 5.3Role和Claims授权「深入浅出ASP.NET Core系列」

    希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,码字辛苦,如果你吃了蛋觉得味道不错,希望点个赞,谢谢关注. Role授权 这是一种Asp.Net常用的传统的授权方法,当我们在 ...

  6. 1.4部署到IIS「深入浅出ASP.NET Core系列」

    希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,谢谢关注. 很多人第一次在IIS中部署Asp.Net Core App的人都会遇到问题,会发现原来的部署方式无法运行Asp.N ...

  7. 4.1ASP.NET Core请求过程「深入浅出ASP.NET Core系列」

    希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,谢谢关注. HTTP请求过程 这里展示整体的HTTP请求的过程,这里化繁为简,保留了主干流程: 从浏览器输入域名开始,这里忽略 ...

  8. 4.2WebHost配置「深入浅出ASP.NET Core系列」

    希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,谢谢关注. WebHost配置 覆盖配置文件和修改启动URL 覆盖配置文件和修改启动URL是经常使用的地方,覆盖配置文件可以自 ...

  9. 5.1基于JWT的认证和授权「深入浅出ASP.NET Core系列」

    希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,码字辛苦,如果你吃了蛋觉得味道不错,希望点个赞,谢谢关注. Cookie-Based认证 认证流程 我们先看下传统Web端的认 ...

随机推荐

  1. BZOJ_5296_[Cqoi2018]破解D-H协议_BSGS

    BZOJ_5296_[Cqoi2018]破解D-H协议_BSGS Description Diffie-Hellman密钥交换协议是一种简单有效的密钥交换方法.它可以让通讯双方在没有事先约定密钥(密码 ...

  2. cocoapods安装及使用其中 添加新源: gem sources -a https://ruby.taobao.org/

    一.概要 iOS开发时,项目中会引用许多第三方库,CocoaPods(https://github.com/CocoaPods/CocoaPods)可以用来方便的统一管理这些第三方库. 二.安装 由于 ...

  3. ||与&&的返回值

    当你准备携带你的配剑杀向江湖的时候,当你准备进入js这门语言的时候,你会遇到很多||与&&的问题.那么对于他们的返回值你知道多少呢? 在此之前我们来聊一个大家都知道的知识:js中值转换 ...

  4. NavigationView头部设置监听事件

    直接写解决方法吧: 1.将XML里的静态引入删除: <android.support.design.widget.NavigationView android:id="@+id/nav ...

  5. 关于” 记一次logback传输日志到logstash根据自定义设置动态创建ElasticSearch索引” 这篇博客相关的优化采坑记录

    之前写过一篇博客是关于记录日志的简单方式的   主要就是  应用->redis->logstash->elasticsearch 整个流程的配置方法和过程的 虽然我们部分线上应用使用 ...

  6. FreeSql.Repository 通用仓储层功能

    前言 好多年前,DAL 作为数据库访问层,其实是非常流行的命名方式. 不知道从什么时候开始,仓储层成了新的时尚名词.目前了解到,许多人只要在项目中看见 DAL 就会觉得很 low,但是比较可笑的一点是 ...

  7. 深入vue - 源码目录及构建过程分析

     公众号原文链接:深入vue - 源码目录及构建过程分析   喜欢本文可以扫描下方二维码关注我的公众号 「前端小苑」 ​“ 本文主要梳理一下vue代码的目录,以及vue代码构建流程,旨在对vue源码整 ...

  8. Docker安装+HelloWorld+运行Tomcat

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 上一篇已经讲解了为什么需要Docker?,相信大家已 ...

  9. C++对象生存期&&static

    生存期,即从诞生到消失的时间段,在生存期内,对象的值或保持不变,知道改变他的值为止.对象生存期分为静态生存期和动态生存期两种. 静态生存期 指对象的生存期与程序运行期相同.在namespace中声明的 ...

  10. C语言中#undef作用

    #undef 作用:取消定义的宏 指令格式:#undef 标识符 1 #include <stdio.h> 2 3 #define MAX 5 4 5 int main() { 6 pri ...