热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#IoC(nversionofControl)、DI(DependencyInjection)

程序中经常用到IoC(控制反转)和DI(依赖注入),但对其概念的认识也是模模糊糊,今天就详细的了

 

程序中经常用到IoC(控制反转)和DI(依赖注入),但对其概念的认识也是模模糊糊,今天就详细的了解下

  • 什么是IOC(Inversion of Control )
  • 什么是DI(Dependency Injection )
  • 实现依赖注入的方式
  • IOC、DI的优点

IOC控制反转

回想下我们在大学里,有时候需要去参加一些组织活动或者是无聊的讲座。就把College当成类,活动或讲座看成Event。让我们试着把College和Event与IOC联系起来

 

 

假设我们有两个类,College和TechEvents,如上图代码,你会发现一些问题:

  1. 这两个类彼此紧密耦合。我们不能有一个没有TecheEvents的College,因为TecheEvents对象是在College构造函数中创建的
  2. 如果我修改了TechEvents,我也需要编译或修改College类
  3. College控制Event的产生。College现在是一个单一事件(社团活动)的组织,如果有其他事件(如FootballEvent、PartyEvent)发生,那就需要修改College,因为College是直接引用的Events

现在我们需要解决这个问题,否则在College里,不能有其他的Event

解决这个问题的办法是把事件组织的控制转移到其他地方,就是我们常说的IOC(控制反转)。把控制权反转给其他实体,而不是直接在College中。

IOC的原理是什么呢?

Don't Call Me, we will call you

换言之,Main类不应该有聚合类的具体实现,而应该依赖于该类的抽象。College类应该依赖于TechEvents类的抽象(接口或者抽象类)

 

//1.创建用来实现抽象的接口interface IEvent { void LoadEventDetail(); }//2.所有的Event类应实现IEvent接口class TechEvents : IEvent{public void LoadEventDetail(){Console.WriteLine("Technology Event Details");}}class FootballEvent:IEvent{public void LoadEventDetail(){Console.WriteLine("Football Event Details");}}class PartyEvent:IEvent{public void LoadEventDetail(){Console.WriteLine("Party Event Details");}}//3.College构造函数说:I will call the Eventclass College{private IEvent _events = null;public College(IEvent ie){this._events = ie;}public void GetEvents(){this._events.LoadEventDetail();}}

DI依赖注入

IOC通过DI完成。它解释如何将具体实现注入到使用了抽象类或接口的类中。依赖注入的主要思想是减少类之间的耦合,并将抽象和具体实现的绑定从依赖类中移除。简单来说,DI是一个对象如何知道被抽象的其他对象

实现依赖注入的方法主要有4种。

1. 构造器注入

 上面已经讨论了这种方法,具体类的对象被传递给依赖类的构造函数。

class College{private IEvent _events = null;public College(IEvent ie){this._events = ie;}public void GetEvents(){this._events.LoadEventDetail();}}

事件对象由构造器注入,使其松散耦合。College类将完成它的工作,如果它想获取事件的相关细节,它将基于他想调用的事件,在构造函数中调用它。

等同于

College coll = new College(new FootballEvent());

除了这个优点,另一个优点是当Event发生改变或增加事件,College不需要关心这些。

2. 属性注入

这是最常用的方法,我们通过创建一个类型为接口的属性来注入具体的类

class College{private IEvent _events;public IEvent MyEvent{set{_events = value;}}
//....}

MyEvent属性的setter将具体对象绑定到接口。类与具体对象松散耦合。现在,Event类任何对象的变化都不会影响到College类。

College coll = new College();
coll.MyEvent
= new FootballEvent();

3. 方法注入

这个方法中,具体的类对象通过方法参数传递给依赖类。

class College
{
private IEvent _events; public void GetEvent(IEvent myevent) { this._events = myevent; }
//....
}

如上所示,通过GetEvent方法调用College事件,其中事件的类型作为抽象类型的参数传递。

College col1 = new College();col1.GetEvent(new FootballEvent());col1.GetEvents();

4. 服务定位注入

service locator就像一个简单的运行时mapper。允许在运行时添加代码,而不必重新编译应用程序,并且在某些情况下不必重新启动。

class College{private IEvent _events = null;EventLocator el = new EventLocator();public College(int index){this._events = el.LocateEvent(index);}public void GetEvents(){this._events.LoadEventDetail();}}class EventLocator{public IEvent LocateEvent(int index){if (index == 1) return new FootballEvent();else if (index == 2) return new PartyEvent();else return new TechEvents();}}

上面的代码中,在Events和College类之间有一个EventLocator类,它帮助我在不知道具体类型的情况下定位服务。通过构造函数中的index值,来调用第三方进行定位,并返回给构造函数。EventLocator类的任何改变都不会影响到College类。

College coll = new College(1);
coll.GetEvents();

实施这一原则的优点

  • 它有助于类的解耦。
  • 由于解耦,增加了代码的可重用性。
  • 提升了代码的可维护性和测试。

 总结:控制反转(IOC)讨论谁将发起调用,而依赖注入(DI)讨论一个对象如何通过抽象获得对其他对象的依赖。

 

参考地址:https://www.c-sharpcorner.com/UploadFile/cda5ba/dependency-injection-di-and-inversion-of-control-ioc/ 

转:https://www.cnblogs.com/pashanhu/p/9656716.html



推荐阅读
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • 解决VS写C#项目导入MySQL数据源报错“You have a usable connection already”问题的正确方法
    本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 导出功能protectedvoidbtnExport(objectsender,EventArgse){用来打开下载窗口stringfileName中 ... [详细]
  • Final关键字的含义及用法详解
    本文详细介绍了Java中final关键字的含义和用法。final关键字可以修饰非抽象类、非抽象类成员方法和变量。final类不能被继承,final类中的方法默认是final的。final方法不能被子类的方法覆盖,但可以被继承。final成员变量表示常量,只能被赋值一次,赋值后值不再改变。文章还讨论了final类和final方法的应用场景,以及使用final方法的两个原因:锁定方法防止修改和提高执行效率。 ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
author-avatar
淡若无诤
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有