C# IoC控制反转学习笔记
一、什么是IOC
IoC-Invertion of Control,即控制反转,是一种程序设计思想。
先初步了解几个概念:
依赖(Dependency):就是有联系,表示一个类依赖于另一个类。
依赖倒置原则(DIP):设计模式六大原则之一,是一种软件架构设计原则。
控制反转(IoC):一种软件设计原则,上层对下层的依赖(即底层模块的获得)交给第三方。
依赖注入(DI):实现IoC的一种方式、手段。
IoC容器:依赖注入的框架,用来映射依赖,管理对象的创建和生存周期。
二、依赖
依赖就是有联系,有地方使用它就是有依赖它,下面看一个简单的示例:
class Program{class BMW{public string Show(){return "宝马";}}class ChinesePeople{private BMW bmw = new BMW();public void Run(){Console.WriteLine($"今天开{bmw.Show()}上班");}}static void Main(string[] args){ChinesePeople people = new ChinesePeople();BMW bmw = new BMW();people.Run();Console.Read();}}
上面中国人开着宝马去上班,客户端有使用中国人、宝马汽车两个对象,中国人中有使用对象宝马汽车,我们可以从中找到三个依赖关系:
客户端依赖对象ChinesePeople;
客户端依赖对象BMW;
ChinesePeople依赖对象BMW;
三、依赖倒置原则
过些日子来了新需求,中国人不仅要开宝马去上班,还要开奔驰去上班,如果按照上面直接依赖关系的方式去做,我们就需要修改ChinesePeople类,让它实现一个参数为宝马的重载方法Run()。显然这样不是好的设计,我们总不能每次新增一种汽车(即修改下层模块)都要去修改ChinesePeople类吧(相对于汽车为上层模块),太麻烦了。。。
先简单分析一下,耦合关系就是依赖关系,如果依赖关系很重,牵一发而动全身,将很难维护扩展,耦合关系越少,系统会越稳定,因此要较少依赖。
定义:
A.高层模块不应依赖于底层模块,两者应该依赖于抽象。
B.抽象不应该依赖于细节,细节应该依赖于抽象。
在这个图中,我们发现高层模块定义接口,将不直接依赖于下层模块,下层模块负责实现高层模块定义的接口,下面看一下示例:
class Program{interface ICar{string Show();}class BMW : ICar{public string Show(){return "宝马";}}class BenZ : ICar{public string Show(){return "奔驰";}}interface IPeople{void Run(ICar car);}class ChinesePeople : IPeople{public void Run(ICar car){Console.WriteLine($"今天开{car.Show()}上班");}}static void Main(string[] args){ICar bmw = new BMW();ICar benz = new BenZ();IPeople people = new ChinesePeople();people.Run(bmw);people.Run(benz);Console.Read();}}
分析:上面代码中,ChinesePeople类不再依赖于具体的汽车,而是依赖于汽车的抽象,这样使得不管换什么样的汽车品牌,中国人都是可以开着去上班的,而且不需要修改ChinesePeople类。想一下,这样是不是挺好的。我们可以得出:上层不再依赖细节,相比面向实现,面向接口较好,因为抽象相比细节要更稳定。
四、控制反转
上面示例中,我们实现了具体的人和具体的汽车的隔离,具体人只和汽车的接口有关。但是Program中Main方法里的具体对象写死了,控制权变小,当我要修改美国人开着福特去上班时,就不得不要去修改代码,那怎么把控制权转移呢?
下面看一个简单的示例(请先添加System.Configuration引用):
interface ICar{string Show();}interface IPeople{void Run(ICar car);}
class BMW : ICar{public string Show(){return "宝马";}}class ChinesePeople : IPeople{public void Run(ICar car){Console.WriteLine($"今天开{car.Show()}上班");}}<?xml version="1.0" encoding="utf-8" ?>
<configuration><startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" /></startup><appSettings><add key="People" value="LinkTo.Test.ConsoleIoC.ChinesePeople,LinkTo.Test.ConsoleIoC"/><add key="Car" value="LinkTo.Test.ConsoleIoC.BMW,LinkTo.Test.ConsoleIoC"/></appSettings>
</configuration>
class Program{static void Main(string[] args){#region 反射+配置文件实现Iocstring people = ConfigurationManager.AppSettings["People"];string car = ConfigurationManager.AppSettings["Car"];Assembly assemblyPeople = Assembly.Load(people.Split(',')[1]);Assembly assemblyCar = Assembly.Load(car.Split(',')[1]);Type typePeople = assemblyPeople.GetType(people.Split(',')[0]);Type typeCar = assemblyPeople.GetType(car.Split(',')[0]);IPeople ipeople = (IPeople)Activator.CreateInstance(typePeople);ICar icar = (ICar)Activator.CreateInstance(typeCar);ipeople.Run(icar);Console.Read();#endregion}}
上面代码中,我们使用反射+配置文件的方式,将对象创建的控制权转移到了配置文件,这就是所谓的控制反转。
分析:控制反转是将对象创建的控制权交给了第三方,可以是IoC容器,它就相当于简单工厂。我们要什么对象,工厂就给我们什么对象,这样依赖关系就变了,它们(人和车)都依赖于IoC容器,通过IoC容器建立它们之间的依赖关系。(依赖对象不再直接通过new来获取)
五、依赖注入
上面说到的控制反转,我们了解到是将控制权转移,这是我们的目的。配置文件+反射是一种实现,而依赖注入则提供的是一种思想,或者说是实现IoC的手段。
依赖注入是将对象的创建和绑定转移到被依赖对象的外部来实现,一般使用哪些方法来实现呢?
1、构造函数注入
class ChinesePeopleConstructor{private readonly ICar _car;//依赖注入:构造函数注入public ChinesePeopleConstructor(ICar car){_car = car;}public void Run(){Console.WriteLine($"今天开{_car.Show()}上班");}}class Program{static void Main(string[] args){#region 依赖注入:构造函数注入ICar bmw = new BMW();ChinesePeopleConstructor people = new ChinesePeopleConstructor(bmw);people.Run();Console.Read();#endregion}}
2、属性注入
class ChinesePeopleProperty{//依赖注入:属性注入public ICar Car { get; set; }public void Run(){Console.WriteLine($"今天开{Car.Show()}上班");}}class Program{static void Main(string[] args){#region 依赖注入:属性注入ICar bmw = new BMW();ChinesePeopleProperty people = new ChinesePeopleProperty{Car = bmw};people.Run();Console.Read();#endregion}}
3、接口注入
interface IDependent{void SetDependent(ICar icar);}class ChinesePeopleInterface : IDependent{private ICar _car;//依赖注入:接口注入public void SetDependent(ICar car){_car = car;}public void Run(){Console.WriteLine($"今天开{_car.Show()}上班");}}class Program{static void Main(string[] args){#region 依赖注入:接口注入ICar bmw = new BMW();ChinesePeopleInterface people = new ChinesePeopleInterface();people.SetDependent(bmw);people.Run();Console.Read();#endregion}}
六、IoC容器
IoC容器是一个DI框架,主要功能有一下几点:
A.动态创建、注入依赖对象;
B.管理对象生命周期;
C.映射依赖关系;
常见的IoC容器:Spring.NET,Castle Windsor, Ninject,Autofac,Unity
参考自: https://www.cnblogs.com/jdzhang/p/7104351.html
相关文章:
C# IoC控制反转学习笔记
一、什么是IOC IoC-Invertion of Control,即控制反转,是一种程序设计思想。 先初步了解几个概念: 依赖(Dependency):就是有联系,表示一个类依赖于另一个类。 依赖倒置原则(DIP&a…...
Python解题 - CSDN周赛第33期
本期四道题全考过,题解在网上也都搜得到。。。没有想法,顺手水一份题解吧。 第一题:奇偶排序 给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数。 输入描述:第一行输入整数n。(1<n<…...
Session攻击
Session攻击Session攻击简介主要攻击方式会话预测会话劫持中间人攻击会话固定Session攻击简介 Session对于Web应用是最重要的,也是最复杂的。对于Web应用程序来说,加强安全性的首要原则就是:不要信任来自客户端的数据,一定要进行数据验证以及…...
【Linux】Shell详解
😊😊作者简介😊😊 : 大家好,我是南瓜籽,一个在校大二学生,我将会持续分享Java相关知识。 🎉🎉个人主页🎉🎉 : 南瓜籽的主页…...
汉字找不同隐私协议
本隐私信息保护政策版本:2021 V1 一、重要提示 请您(以下亦称“用户”)在使用本平台App时仔细阅读本协议之全部条款,并确认您已完全理解本协议之规定,尤其是涉及您的重大权益及义务的加粗或划线条款。如您对协议有任…...
CEC2017:斑马优化算法(Zebra Optimization Algorithm,ZOA)求解cec2017(提供MATLAB代码)
一、斑马优化算法 斑马优化算法(Zebra Optimization Algorithm,ZOA)Eva Trojovsk等人于2022年提出,其模拟斑马的觅食和对捕食者攻击的防御行为。 斑马因身上有起保护作用的斑纹而得名。没有任何动物比斑马的皮毛更与众不同。斑…...
【Linux要笑着学】进程创建 | 进程终止 | slab分派器
爆笑教程《看表情包学Linux》👈 猛戳订阅!💭 写在前面:本章我们主要讲解进程的创建与终止。首先讲解进程创建,fork 函数是我们早在讲解 "进程的概念" 章节就提到过的一个函数&#…...
数据资产管理建设思考(二)
关于数据资产管理,近两年是数据治理行业中一个热点话题,当然有我们前面提到的国家的政策支持及方向指引的原因。另一方面我们做数据治理的同行们从学习吸收国外优秀的数据治理理论,进一步在实践中思考如何应用理论,并结合我们国家…...
微软发布多模态版ChatGPT!取名“宇宙一代”
文|CoCo酱Ludwig Wittgenstein曾说过:“我语言的局限,即是我世界的局限”。大型语言模型(LLM)已成功地作为各种自然语言任务的通用接口,只要我们能够将输入和输出转换为文本,就可以将基于LLM的接…...
【学习笔记】深入理解JVM之对象的实例化
参考尚硅谷JVM 102 - 106 集 首发地址:地址 1、JVM对象的实例化 1.1 对象的创建方式 对象有一下几种创建对象的方式 new Object object new Object();Class的newInstance() Object object Object.class.newInstance();Constructor的newInstance(…...
IP协议的漏洞及防护措施
文章目录一、TCP/IP协议族二、IP协议三、IP协议的安全问题及防护措施一、TCP/IP协议族 二、IP协议 网际协议(Internet Protocol,IP)是TCP/IP协议族的核心,也是网际层最重要的协议。 IP数据报由首部和数据两部分组成;…...
Linux命令·mkdir
linux mkdir 命令用来创建指定的名称的目录,要求创建目录的用户在当前目录中具有写权限,并且指定的目录名不能是当前目录中已有的目录。1.命令格式:mkdir [选项] 目录...2.命令功能:通过 mkdir 命令可以实现…...
智能家居项目(八)之树莓派+摄像头进行人脸识别
目录 1、编辑Camera.c 2、编辑contrlDevices.h 3、编辑mainPro.c 4、进行编译: 5、运行结果: ./test1 6、项目图片演示 智能家居项目(七)之Libcurl库与HTTPS协议实现人脸识别_Love小羽的博客-CSDN博客 经过上一篇文章&…...
渗透测试之地基服务篇:无线攻防之钓鱼无线攻击(上)
简介 渗透测试-地基篇 该篇章目的是重新牢固地基,加强每日训练操作的笔记,在记录地基笔记中会有很多跳跃性思维的操作和方式方法,望大家能共同加油学到东西。 请注意 : 本文仅用于技术讨论与研究,对于所有笔记中复现…...
「ABAP」一文带你入门OPEN SQL中的SELECT查询(附超详细案例解析)
💂作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。在学习工作中,我通常使用偏后…...
【搞透C语言指针】那年我双手插兜, 不知道指针是我的对手
☃️内容专栏:【C语言】进阶部分 ☃️本文概括: 征服C语言指针!一篇文章搞清楚指针的全部要点。 ☃️本文作者:花香碟自来_ ☃️发布时间:2023.3.3 目录 一、字符指针 二、指针数组 三、数组指针 1.数组指针的定义…...
如何从 Android 手机上的 SD 卡恢复已删除的照片
为了扩展手机的存储空间,很多人都会在安卓手机上插入一张SD卡来存储一些大文件,比如电影、照片、视频等。虽然SD卡给我们带来了很大的方便,但我们还是避免不了数据丢失一些事故造成的。您是否正在为 SD 卡上的照片意外丢失而苦恼?…...
01-前端-htmlcss
文章目录HTML&CSS1,HTML1.1 介绍1.2 快速入门1.3 基础标签1.3.1 标题标签1.3.2 hr标签1.3.3 字体标签1.3.4 换行标签1.3.5 段落标签1.3.6 加粗、斜体、下划线标签1.3.7 居中标签1.3.8 案例1.4 图片、音频、视频标签1.5 超链接标签1.6 列表标签1.7 表格标签1.8 布…...
【YOLO系列】YOLOv5超详细解读(网络详解)
前言 吼吼!终于来到了YOLOv5啦! 首先,一个热知识:YOLOv5没有发表正式论文哦~ 为什么呢?可能YOLOv5项目的作者Glenn Jocher还在吃帽子吧,hh 目录 前言 一、YOLOv5的网络结构 二、输入端 (1…...
从 ChatGPT 爆火回溯 NLP 技术
ChatGPT 火遍了全网,多个话题频频登上热搜。见证了自然语言处理(NLP)技术的重大突破,体验到通用技术的无限魅力。GPT 模型是一种 NLP 模型,使用多层变换器(Transformer)来预测下一个单词的概率分…...
面了 6 家大厂,并拿下 5 家 offer,进大厂好像也没有那么困难吧....
前言 二月份的时候因为换工作的缘故,陆续参加了华为、蚂蚁、字节跳动、PDD、百度、Paypal 的社招面试,除了字节跳动流程较长,我主动结束面试以外,其他的都顺利拿到了 Offer。 最近时间稍微宽裕点了,写个面经…...
四、Spring对IoC的实现
1.IoC 控制反转 控制反转是一种思想。控制反转是为了降低程序耦合度,提高程序扩展力,达到OCP原则,达到DIP原则。控制反转,反转的是什么? 将对象的创建权利交出去,交给第三方容器负责。将对象和对象之间关系…...
Java语言如何求平方根
问题 在编程时,会遇到求平方根的问题,本次问题讲到如何使用Java来求解平方根。 方法 使用java.lang.Math类的sqrt(double)方法求平方根。Math是java.lang包中的类,所以就可以直接使用这个类。Double为对象中的基本类型。例如求正整数16的平方…...
C++20中的span容器
一.span容器 span 是 C20 中引入的一个新的标准容器,它用于表示连续的一段内存区间,类似于一个轻量级的只读数组容器。 span 是一个轻量级的非拥有式容器,它提供了对连续内存的引用。 span 的主要用途是作为函数参数,可以避免不…...
codeforces周赛div3#855记录
目录 总结 一,A. Is It a Cat? 二,B. Count the Number of Pairs 三,C1. Powering the Hero (easy version) 四,C2. Powering the Hero (hard version) 总结 真羡慕ACM校队的同学,能AC七八题,甚至ak …...
2022年考研结果已出,你上岸了吗?
官方公布:2022年考研人数为457万。 2月20号左右,全国考研分数已经陆续公布,现在已经过去一周左右的时间了,你上岸了吗,还是在等调剂,或者已经知道落榜不知道何去何从? 考研的热潮在近几年席卷…...
2023 工业互联网平台:智慧制硅厂 Web SCADA 生产线
我国目前是全球最大的工业硅生产国、消费国和贸易国,且未来该产业的主要增量也将来源于我国。绿色低碳发展已成为全球大趋势和国际社会的共识,随着我国“双碳”目标的推进,光伏产业链快速发展,在光伏装机需求的带动下,…...
6-2 SpringCloud快速开发入门:声明式服务消费 Feign实现消费者
声明式服务消费 Feign实现消费者 使用 Feign实现消费者,我们通过下面步骤进行: 第一步:创建普通 Spring Boot工程 第二步:添加依赖 <dependencies><!--SpringCloud 集成 eureka 客户端的起步依赖--><dependency>…...
Git-学习笔记01【Git简介及安装使用】
Java后端 学习路线 笔记汇总表【黑马-传智播客】Git-学习笔记01【Git简介及安装使用】Git-学习笔记02【Git连接远程仓库】Git-学习笔记03【Git分支】目录 01-git的历史 02-git和svn的对比 03-git的安装 04-向本地仓库中添加文件 05-修改文件内容并提交 06-删除本地仓库中…...
【Python】控制自己的手机拍照,并自动发送到邮箱
前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 今天这个案例,就是控制自己的摄像头拍照, 并且把拍下来的照片,通过邮件发到自己的邮箱里。 想完成今天的这个案例,只要记住一个重点:你需要一个摄像头 思路…...
济南品牌网站建设/软文广告
本文来自CMU的博士,MIT的博士后,vision.ai的联合创始人Tomasz Malisiewicz的个人博客文章,阅读本文,你可以更好的理解计算机视觉是怎么一回事,同时对机器学习是如何随着时间缓慢发展的也有个直观的认识。 以下为正文&a…...
政府大型网站建设/百度客服转人工
Lex自动地表示把输入串词法结构的正规式及相应的动作转换成一个宿主语言的程序,即词法分析程序,它有一个固定的名字yyler,在这里yyler是一个C语言的程序。Yylex将识别出输入串中的词形,并且在识别出某词形…...
网站建设项目的预表/快速优化系统
导读: ActiveSync应用层程序协议分析-RAPI的握手过程 转载时请注明出处和作者联系方式作者联系方式:李先静 ActiveSync与Window Mobile之间的通信协议并不复杂,在RNDISUSBNET之上运行TCP/IP,而TCP/IP之上的应用层协议包括RAPI和RR…...
做网站用哪种编程语言/seo搜索引擎入门教程
早些时戴尔发布了SAN Headquarters(SAN HQ) v2.2。这个版本的SAN HQ给用户带来了一些全新的和令人激动的特性。 如果您已经是SAN HQ的用户了,您应该能够意识到SAN HQ的诸多益处。通过发现性能的瓶颈,SAN HQ可以改善整个SAN系统的性能。通过发现那些未被有…...
dz网站地图怎么做/广点通官网
目录 ThreadLocal InheritableThreadLocal TransmittableThreadLocal 本文主要介绍ThreadLocal、InheritableThreadLocal、TransmittableThreadLocal三者之间区别、如何使用、什么场景使用以及对原理和源码的介绍。介绍原理的时候通过最直白、最易懂的语言争取让大家了解三者…...
如何转换page到wordpress/现在推广平台哪家最好
OpenCv图像处理之图像归一化归一化中心化标准化归一化 图像处理中,图像单通道像素值为0~255之间的uchar类型,通常使用min-max归一化将其转化为0~1区间之间,既不会改变数据的分布和信息存储,又加速了后续网络的计算。 min-max归一…...