什么是依赖注入?不管是js中的一些前端框架还是,java,C#等中的一些后端语言开发框架中,都会涉及这个的词语:依赖注入,单纯听这个词汇好像很厉害的样子,大部分人都会对未知的事物产生排斥和畏惧,但是其实只要通过简单学习后你会发现其实并没有想象中那么复杂。

1,基本概念

依赖注入?控制反转?

  依赖注入控制反转的一种具体实现方式,那什么又是控制反转:它是面向对象编程中的一种设计原则,其作用主要用来减低计算机代码之间的耦合度,

  其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

2,概念理解与运用

如果有一定的面向对象思想其实要理解这一概念的并不算太难,我们常规面向对象最基本的思想就是我们会把某些业务模块需要封装成为一个类,然后在需要的地方去实例化调用,我们不妨举一个生活中的简单栗子,把它体现到代码之中后,看看代码不使用依赖注入和使用依赖注入有什么区别:

如果把我自己比作一个类,假定我这个类里面有工作“Work()”和休息放假“Holiday()”两个函数,然后我在工作和休息两个函数中都会用到我的苹果手机,工作“Work()”函数中会用手机打电话和发邮件,休息“Holiday()”函数会用手机玩游戏、上网还有看视频,我们把手机也看成另一个类,手机类分别实现了:打电话:Call()、发邮件:Eamil()、玩游戏:PlayGame()、上网:Internet()、看视频:VideoPlay()五个函数。代码如下:

    public class Person
{ }
public class Me : Person
{
public void Work()
{
//…… 省略若干代码
iphone phone = new iphone();
phone.Call();
phone.Eamil();
} public void Holiday()
{
//…… 省略若干代码
iphone phone = new iphone();
phone.PlayGame();
phone.VideoPlay();
phone.Internet();
}
} public class iphone
{
public void Call()
{
//…… 省略若干代码
Console.WriteLine($"iphone手机打电话");
} public void Eamil()
{
//…… 省略若干代码
Console.WriteLine($"iphone手机发送邮件");
} public void PlayGame()
{
//…… 省略若干代码
Console.WriteLine($"iphone手机玩游戏");
} public void VideoPlay()
{
//…… 省略若干代码
Console.WriteLine($"iphone手机播放视频");
} public void Internet()
{
//…… 省略若干代码
Console.WriteLine($"iphone手机上网");
}
}

调用代码:

    public class Program
{
public static void Main(string[] args)
{
int[] Holiday = { , };
//获取当前时间
DateTime time = DateTime.Now;
//实例化Me对象
Me me = new Me(); if (Holiday.Contains((int)time.DayOfWeek))
{
//如果当前时间为周六,周日,执行Holiday
me.Holiday();
}
else
{
//如果当前时间不为周六,周日,执行Work
me.Work();
}
}
}

看到这个代码我们觉得很OK,终于可以愉快的工作和休息了,但是好景不长,有一天我从苹果手机换成了华为手机,为了我代码可以正常运行,我必须把所有实例化过iphone类的地方改成实例化华为类,在将来我每换一次手机,我的对应的实例也会跟着改变,代码实例对象的地方存在耦合。所以我们要想办法解耦,怎么处理呢?

    public class Person
{ }
public class Me : Person
{
private phone myphone; public Me(phone _phone)
{
myphone = _phone;
} public void Work()
{
//…… 省略若干代码
myphone.Call();
myphone.Eamil();
} public void Holiday()
{
//…… 省略若干代码
myphone.PlayGame();
myphone.VideoPlay();
myphone.Internet();
}
}
public abstract class phone
{
public abstract void Call();
public abstract void Eamil();
public abstract void PlayGame();
public abstract void Internet();
public abstract void VideoPlay();
} public class iphone : phone
{
public override void Call()
{
//…… 省略若干代码
Console.WriteLine($"iphone手机打电话");
} public override void Eamil()
{
//…… 省略若干代码
Console.WriteLine($"iphone手机发送邮件");
} public override void PlayGame()
{
//…… 省略若干代码
Console.WriteLine($"iphone手机玩游戏");
} public override void VideoPlay()
{
//…… 省略若干代码
Console.WriteLine($"iphone手机播放视频");
} public override void Internet()
{
//…… 省略若干代码
Console.WriteLine($"iphone手机上网");
}
} public class huaweiphone : phone
{
public override void Call()
{
//…… 省略若干代码
Console.WriteLine($"华为手机打电话");
} public override void Eamil()
{
//…… 省略若干代码
Console.WriteLine($"华为手机发送邮件");
} public override void PlayGame()
{
//…… 省略若干代码
Console.WriteLine($"华为手机玩游戏");
} public override void VideoPlay()
{
//…… 省略若干代码
Console.WriteLine($"华为手机播放视频");
} public override void Internet()
{
//…… 省略若干代码
Console.WriteLine($"华为手机上网");
}
}

代码标红的地方是主要涉及依赖注入的地方,我们把手机类作为一个父类,然后华为和iPhone都继承此类,然后我们把手机类作为Me类的成员,这样改动后我们的调用代码如下

     public class Program
{
public static void Main(string[] args)
{
int[] Holiday = { , };
//获取当前时间
DateTime time = DateTime.Now;
//实例化手机对象
phone phone = new huaweiphone();
//实例化Me对象
Me me = new Me(phone); if (Holiday.Contains((int)time.DayOfWeek))
{
//如果当前时间为周六,周日,执行Holiday
me.Holiday();
}
else
{
//如果当前时间不为周六,周日,执行Work
me.Work();
}
}
}

代码这样更改之后不管我们要用iPhone类还是华为类还是其他新的手机类去实现我们的Holiday()和Work()中的函数,我们不需要对Me类做任何改动,只需要去改变传输的对象,在调用时灵活的将我们所需要的依赖对象注入到Me类之中,这就就是传说中的依赖注入。

回看前面的例子再用我自己的话来理解依赖注入:就是把依赖部分(代码不可控或者经常变动的耦合的部分)变成一个抽象的成员(类、抽象类或接口),然后根据具体所需要的实例去灵活的注入依赖,来达到控制反转的效果,从而实现代码解耦。

上面这个简单的例子中依赖部分就是iPhone类,华为类这种可能存在变动的类,每种手机具体实现打电话Call(),发邮件Eamil()等功能的方式可能都有差异,我们只能在具体要用到的时候才会知道到底要用哪一种手机,所以在具体调用的时候去注入手机对象是相对灵活而且耦合度低的一种方案。

3,C#常用的依赖注入方式

  1,通过构造器进行依赖注入

  2,通过属性的访问器进行依赖注入

  3,通过接口实现依赖注入

  4,通过反射,特性也可以实现依赖注入

我们上面例子是通过构造函数实现的简单的依赖注入,其他几种方式在搞清楚代码基础语法概率之后其实也都差不多,我就不一一举例了,不管用什么方式实现依赖注入,理解其中的基本思想是最重要的。

浅谈C#依赖注入的更多相关文章

  1. 浅谈_依赖注入 asp.net core

    1.1什么是依赖 我们先看下图 可以简单理解,一个HomeController类使用到了DBContext类,而这种关系是有偶然性,临时性,弱关系的,但是DBContext的变化会影响到HomeCon ...

  2. 浅谈(IOC)依赖注入与控制反转(DI)

    前言:参考了百度文献和https://www.cnblogs.com/liuqifeng/p/11077592.html以及http://www.cnblogs.com/leoo2sk/archive ...

  3. 浅谈spring依赖注入

    了解依赖注入 前言 先了解下控制反转--转自知乎的国哥 如果一个类A 的功能实现需要借助于类B,那么就称类B是类A的依赖,如果在类A的内部去实例化类B,那么两者之间会出现较高的耦合,一旦类B出现了问题 ...

  4. 浅谈WPF依赖项属性

    浅谈WPF依赖项属性 0. 引言 依赖项属性虽然在使用上和CLR属性一样,但是它是WPF特有的,不同于CLR属性.只是封装为我们常用CLR的属性,在语法使用上和CLR属性一样.WPF中一些功能:动画, ...

  5. 以英雄联盟的方式建模,谈对依赖注入(DI)的理解以及Autofac的用法(一)

    一.前言 近期在探索分层架构和架构设计,选择了领域驱动作为5年.Net开发后的新的方向,不可避免的接触了IoC/DI方面的技术.目前通过反射或其他方法都已实现,但只知其一,并没有考虑为什么要这么做,同 ...

  6. Spring5.0源码学习系列之浅谈循环依赖问题

    前言介绍 附录:Spring源码学习专栏 在上一章的学习中,我们对Bean的创建有了一个粗略的了解,接着本文浅谈Spring循环依赖问题,这是一个面试比较常见的问题 1.什么是循环依赖? 所谓的循环依 ...

  7. 浅谈微信smali注入

    作者:郭少雷 搞android搞了几年也没搞出个啥牛逼app出来,眼看时下最火的app微信如此火热,实在想搞搞它,索性就想着给它加点东西进去. 以下内容纯属本人个人爱好,仅限个人学习android用途 ...

  8. 谈谈php里的IOC控制反转,DI依赖注入

    理论 发现问题 在深入细节之前,需要确保我们理解"IOC控制反转"和"DI依赖注入"是什么,能够解决什么问题,这些在维基百科中有非常清晰的说明. 控制反转(In ...

  9. 谈谈php里的IOC控制反转,DI依赖注入(转)

    转自:http://www.cnblogs.com/qq120848369/p/6129483.html 发现问题 在深入细节之前,需要确保我们理解"IOC控制反转"和" ...

随机推荐

  1. es 基于match_phrase的模糊匹配原理及使用

    [版权声明]:本文章由danvid发布于http://danvid.cnblogs.com/,如需转载或部分使用请注明出处 在业务中经常会遇到类似数据库的"like"的模糊匹配需求 ...

  2. 京东架构师的showtime京东个性化推荐系统实战

    推荐系统核心任务是排序,从线上服务角度看,就是将数据从给定集合中数据选择出来,选出后根据一定规则策略方法进行排序. 线上服务要根据一定规则进行架构设计,架构设计是什么?每一次权衡取舍都是设计,设计需要 ...

  3. pycharm中可以运行脚本但是不能debug脚本

    以前用的时候好好地,但是最近上班突然脚本就不能debug了,debug直接报错,如下所示 上网查过该有的原因: 1.在pycharm中两个地方设置成utf-8,页面右下角和File>settin ...

  4. Ubuntu 16.04下安装谷歌浏览器(转)

    1.进入 Ubuntu 16.04 桌面,按下 Ctrl + Alt + t 键盘组合键,启动终端. 2.在终端中,输入以下命令,将下载源加入到系统的源列表. sudo wget http://www ...

  5. Shell脚本中实现自动补全功能

    对于Linuxer来说,自动补全是再熟悉不过的一个功能了.当你在命令行敲下部分的命令时,肯定会本能地按下Tab键补全完整的命令,当然除了命令补全之外,还有文件名补全. Bash-completion ...

  6. Android_GLSurfaceView

    使用open GL ES 绘制三角形 首先自定义一个GLSurfaceView class MyGLSurceView extends GLSurfaceView { public MyGLSurce ...

  7. js仿qq分组折叠效果

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  8. go import使用及. _的作用解析

    go中import用于导入包.导入之后就可以使用包中的代码. 比如: import( "fmt" ) 在代码中就可以使用fmt包中的方法,如: fmt.Println(" ...

  9. shiro源码篇 - shiro的session共享,你值得拥有

    前言 开心一刻 老师对小明说:"乳就是小的意思,比如乳猪就是小猪,乳名就是小名,请你用乳字造个句" 小明:"我家很穷,只能住在40平米的乳房" 老师:" ...

  10. Spring的第三天AOP之xml版

    Spring的第三天AOP之xml版 ssm框架 spring  AOP介绍 AOP(Aspect Oriented Programming),面向切面编程.它出来的目的并不是去取代oop,而是对它的 ...