C# IoC控制反转学习笔记

article/2025/11/6 21:52:20

一、什么是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


http://chatgpt.dhexx.cn/article/NjDFNP2N.shtml

相关文章

spring -- 控制反转IOC

1.IOC的理论背景 在面向对象设计的软件系统中&#xff0c;它的底层都是由N个对象构成的&#xff0c;各个对象之间通过相互合作&#xff0c;最终实现系统地业务逻辑。 图1 软件系统中耦合的对象 齿轮组中齿轮之间的啮合关系,与软件系统中对象之间的耦合关系非常相似。对象之间…

Java:控制反转

Java中自带的函数或对象都是编写软件的时候写的&#xff0c;当它需要调用你自己编写的数据的时候&#xff0c;它如何又不知道你定义的类&#xff08;对象&#xff09;是什么&#xff0c;里面有什么成员&#xff0c;它无法调用你的代码&#xff0c;这个时候就需要用到控制反转了…

IoC控制反转

IoC控制反转 一、IoC概念和原理1. 什么是IoC2. IoC底层原理 二、IoC过程1. xml配置文件&#xff0c;配置创建的对象2. 有UserService和UserDao类&#xff0c;创建工厂类 三、IoC接口1. IoC思想基于IoC容器完成&#xff0c;IoC容器底层就是Bean工厂2. Spring提供实现IoC容器的两…

IOC 控制反转

文章目录 一.IOC概念二. IOC的体现三.ioc的技术实现三.基于XML的DI1.引用类型属性自动注入 四.包含关系的配置文件五.基于注解的DI五.简单类型的属性赋值1.vaule(简单类型的属性赋值&#xff09;2.自动注入 一.IOC概念 IOC&#xff1a;控制反转&#xff0c;是一个理论&#xf…

浅谈控制反转(IoC)

Inversion of Control 什么是控制反转&#xff1f; 程序的流程控制权相对于传统的面向过程编程而言发生了反转。下面是维基百科的描述 In software engineering, inversion of control (IoC) is a programming principle. IoC inverts the flow of control as compared to tr…

Spring---浅谈IOC

概念 IOC&#xff08;Inversion of Control 控制反转&#xff09;是spring的核心&#xff0c;贯穿始终。所谓IOC&#xff0c;对于spring框架来说&#xff0c;就是由spring来负责控制对象的生命周期和对象间的关系。 传统开发模式与IOC开发模式的对比 传统开发模式&#xff1a;对…

控制反转-Inversion Of Control

一、控制反转 控制反转&#xff08;Inversion of Control&#xff0c;英文缩写为IoC&#xff09;把创建对象的权利交给框架&#xff0c;是框架的重要特征&#xff0c;并非面向对象编程的专业术语。它包括依赖注入&#xff08;Dependency Injection&#xff0c;简称DI&#xff…

微信小程序hamburgers汉堡包css动画

微信小程序hamburgers汉堡包css动画 源码在我的csdn里下载 https://download.csdn.net/download/ozhy111/12201373

汉堡式折叠html,美味的CSS动画汉堡包:hamburgers_html/css_WEB-ITnose

s if you insist, but they’re not accessible as a menu button. Append the class name of the type of hamburger you’re craving: Here’s the list of hamburger-type classes you can choose from: hamburger--arrowhamburger--arrow-rhamburger--arrowalthamburger--a…

LSB 题解

今天来刷一道Misc的题目&#xff0c;LSB原理进行图片隐写 LSB原理 LSB是一种利用人类视觉的局限性设计的幻术 PNG和BMP图片中的图像像素一般是由RGB(RED红 GREEN绿 BLUE蓝)三原色组成 记住&#xff0c;JPG图片是不适合使用LSB隐写的&#xff0c;JPG图片对像数进行了有损压缩…

LSB利器-zsteg

一、Usage # zsteg -h Usage: zsteg [options] filename.png [param_string] -c, --channels X channels (R/G/B/A) or any combination, comma separated valid values: r,g,b,a,rg,bgr,rgba,r3g2b3,... -l, --limi…

【linux】lsb_release -a命令

查看linux发行版本&#xff1a;lsb_release -a 运行该命令时若提示lsb_release命令不存在 不存在&#xff0c;则表明系统未安装该命令&#xff0c;报错如下&#xff1a; 解决方法&#xff1a; 查看 lsb_release 命令属于哪个软件包&#xff0c;命令为yum provides */lsb_rel…

图片LSB隐写(java)

一、隐写原理 LSB隐写原理就是图片中的像素一般是由三种颜色组成&#xff0c;即三原色(红绿蓝)。由这三种原色可以组成其他各种颜色&#xff0c;在png图片的存储中,每个颜色占有8bit,即有256种颜色&#xff0c;一共包含256的三次方颜色&#xff0c;即16777216中颜色。人类的眼睛…

LSB隐写术

前言 LSB全称为 least significant bit&#xff0c;是最低有效位的意思。Lsb图片隐写是基于lsb算法的一种图片隐写术&#xff0c;以下统称为lsb隐写&#xff0c;这是一种常见的信息隐藏方法。当然关于图像的隐写的方法有很多&#xff0c;统称为隐写术&#xff0c; lsb隐写很实…

Linux开发标准LSB简介:Linux Standard Base

目录 Unix/Linux 标准化历史 POSIX Open Group Austin Group LSB LSB 简介 组织架构 工作组 LSB 的标准化流程 认证 认证问题报告 LSB 的历史、现状和将来 实例&#xff1a;lsb_release 的规范定义和实现 结束语 Unix/Linux 标准化历史 标准化目前已经成为 Linu…

LSB 简介

Unix/Linux 标准化历史 标准化目前已经成为 Linux 系统上的一个热门话题。实际上&#xff0c;在 Linux 诞生之初&#xff0c;这个问题就得到了重视。当 Linus 在开发 0.01 版本的 Linux 内核时&#xff0c;就开始关注 POSIX 标准的发展&#xff0c;他在 /include/unistd.h 文件…

图片隐写之LSB(Least Significant Bit)原理及其代码实现

1. 什么是隐写&#xff1f; 隐写术是一门关于信息隐藏的技巧与科学&#xff0c;所谓信息隐藏指的是不让除预期的接收者之外的任何人知晓信息的传递事件或者信息的内容。隐写术的英文叫做Steganography&#xff0c;来源于特里特米乌斯的一本讲述密码学与隐写术的著作Steganogra…

MetaPhlAn2:宏基因组物种组成分析

简介 MetaPhlAn2是分析微生物群落(细菌、古菌、真核生物和病毒)组成的工具&#xff0c;它在宏基因组研究中非常有用&#xff0c;只需一条完命令即可获得微生物的物种丰度信息(扩增子物种组成需要质控、拼接、拆样本、切除引物、比对等步骤&#xff0c;此软件居然分析宏基因组这…

你想要的宏基因组-微生物组知识全在这(2023.4)

欢迎点击上方蓝色”宏基因组”关注我们&#xff01; 宏基因组/微生物组是当今世界科研最热门的研究领域之一&#xff0c;为加强宏基因组学技术和成果交流传播&#xff0c;推动全球华人微生物组领域发展&#xff0c;中科院青年科研人员创立“宏基因组”公众号&#xff0c;联合海…

Kraken2:宏基因组快速物种注释神器

简介 kraken是基于k-mer精确比对&#xff0c;并采用最LCA投票结果快速宏基因组DNA序列进行物种注释的软件。 图. Kraken2分类基本原理 该文章于2014年发表于Genome Biology&#xff0c;目前引用过两千次[1]。详见《Kraken&#xff1a;使用精确比对的超快速宏基因组序列分类软件…