什么是依赖注入?不管是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. 【leetcode】20.有效的括号

    题目 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效.有效字符串需满足:左括号必须用相同类型的右括号闭合.左括号必须以正确的顺序闭合.注意空字符串可被认为 ...

  2. .Net RPC框架Thrift的用法

      关于Thrift 下面是来自百度百科关于Thrift的介绍: thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和引擎,以构建在 C++, Java, Go ...

  3. Jenkins之使用Pyinstaller构建Python应用程序

    目录 1. 极简概述 2. Jenkins配置 2.1 安装JDK 2.2 安装Jenkins 3. 安装Docker 4. 使用PyInstaller构建Python应用程序 4.1 Fork 一个 ...

  4. Nginx反向代理上传大文件报错(failed to load resource : net :: ERR_CONNECTION_RESET)

    转自: https://blog.csdn.net/kinginblue/article/details/50753271?locationNum=14&fps=1 Nginx反向代理上传大文 ...

  5. git第七节---git merge和git rebase

    # git merge和git rebase 都可以进行分支合并 #git merge 合并后保留记录两个分支的记录 #git rebase合并后会展示成一个分支的记录,另一个分支的提交实际生成了一个 ...

  6. python实现定时任务

    定时任务的实现方式有很多种,如windows服务,借助其他定时器jenkins运行脚本等方式.本文介绍的是python中的一个轻量级模块schedule. 安装 pip命令:pip install s ...

  7. shiro教程1(HelloWorld)

    shiro简介 官网 Apache Shiro是一个强大且易用的Java安全框架,执行身份验证.授权.密码和会话管理.使用Shiro的易于理解的API,您可以快速.轻松地获得任何应用程序,从最小的移动 ...

  8. ServerSocket和Socket

    前言 用ServerSocket和Socket做了个Server.Client通信的demo,以及学习下在这个demo过程中用到java.net.java.io包下几个常用的类. Server imp ...

  9. JavaScript之八皇后问题(递归)

      八皇后问题,是一个古老而著名的问题,该问题最早由国际西洋棋棋手马克斯·贝瑟尔(Max Bezzel)于1848年提出.八皇后问题的具体描述为:在\(8\times8\)的国际象棋上摆放8个皇后,使 ...

  10. iOS SDK开发汇总

    以前也做过静态库的开发,不过都是一些简单的调用,最近在做项目的时候,发现其中还有很多问题,所以建个小项目简单记录遇到的问题以及正确的解决办法. 在项目中遇到的问题如下:xib文件获取不到, story ...