ASP.NET + MVC5 入门完整教程三 (下) ---MVC 松耦合
建立松耦合组件
MVC 模式最重要的特性之一视他支持关注分离,希望应用程序中的组件尽可能独立,只有很少的几个可控依赖项。在理想的情况下,每个组件都不了解其他组件,而只是通过抽象接口来处理应用程序的其他区域,这就称为“松耦合”,它使得的应用程序更易于测试和修改。
举一个简单的例子:假设正在编写一个名称为“MyEmailSender”组件用来发送邮件,笔者会实现一个接口,他定义了发送邮件所需要的所有 Public 函数,该接口称为 “IEmailSender”(也就是说IEmailSender是一个接口,MyEmailSender是该接口的一个具体实现)。
应用程序中需要发送电子邮件的任何其他组件,如“PasswordResetHelper”的口令重置辅助程序,那么只需要通过引用该接口中的方法便可以发送一份邮件,而在 PasswordResetHelper 和 MyEmailSender 之间没有直接的依赖关系。如下图表示:
通过引入 IEmailSender ,保证了 PasswordResetHelper 与 MyEmailSender 之间没有直接的依赖项,这样,编程人员可以完全使用另一个邮件发送程序来替换 MyEmailSender 甚至可以用一个模仿实现以进行测试,而无需对 PasswordResetHelper 做任何修改。关于模仿实现,敬请关注
依赖项注入
接口有助于解除组件耦合,这里人面临一个问题:C#未提供内置方法,以方便地创建实现接口对象,除非以 new 关键字创建一个具体组建的实例。如下代码所示:
public class PasswordResethelper
{
public void ResetPassword()
{
IEmailSender mySender = new MyEmailSender();
//调用接口方法 配置email
mySender.SendEmail;
}
}
这种写法破坏了无需修改 PasswordResetHelper 就能替代 MyEmailSender 的目的,这就意味着此刻仅处于组建松耦合的半途,PasswordResetHelper 通过 IEmailSender 接口来配置并发送电子邮件,但是,为了创建实现该接口,必须创建 MyEmailSender 的一个实例,但实际上,事情变更加糟糕,因为 PasswordResetHelper 现在依赖于 MyEmailSender 类以及 IEmailSender 接口,如图所示:
现在需要有种方法,他能获得实现某一接口的对象,而不用去直接创建该对象,这一问题的解决方案称为“依赖项注入(Eependency Injection, DI)”,也称为控制反转(Inversion of Control,IoC)。
DI 是一种实现组件解耦的设计模式。
打断和声明依赖项
DI 模式有两个部分,第一个部分是从组件(此例中PasswordResetHelper)中除去对具体类的依赖项。做法:创建一个类构造器,以所需接口的实现作为其参数
public class PasswordResethelper
{
private IEmailSender emailSender;
public PasswordResetHelper(IEmailSender emailSenderParam)
{
emailSender = emailSenderParam;
}
public void ResetPassword()
{
//调用接口方法 配置email
mySender.SendEmail;
}
}
现在可以将 PasswordResetHelper 类的构造器称为对 IEmailSender 接口声明了一个依赖项,就是说,除非接受一个实现 IEmailSender 接口对象,否则不能创建和使用它。在依赖项声明中,PasswordResetHelper 类不在有 MyEmailSender 的任何相关点,它仅仅依赖于 IEmailSender 接口,简单说来,就是 PasswordResetHelper 不在关心如何实现 IEmailSender 接口。
注射依赖项
DI 模式的第二个部分是在创建 PasswordResetHelper 类实例时,注入由其申明的依赖项,故称为依赖项注入。这实际上意味着,对于打算使用的 IEmailSender 接口,需要决定是用哪一个类来实现,通过这个类创建一个对象,并将该对象作为参数传递给 PasswordResetHelper 构造器。
这种依赖项实在运行时才被注入到 PasswordResetHelper 中,所以只有在 PasswordResetHelper 类实例化期间才会创建IEmailSender 接口的实现类实例,并将其传递给 PasswordResetHelper 构造器。PasswordResetHelper 与依赖接口的实现类之间不存在编译时的依赖项。
使用依赖项注入容器
解决了依赖项问题,但如何对接口的具体实现进行实例化而无须在应用程序的某个其他地方创建依赖项呢?所以任然需要以下语句:
...
IEmailSender sender = new MyEmailSender();
herper =new PasswordResetHelper(sender);
...
为了解决这个问题,引入“依赖项注入容器(Dependency Injection Container, 简称 DI 容器)”,也称为“IoC 容器”。这是一个组件,他在类(如 PasswordResetHelper)所声明的依赖项和用来解决这些依赖项的类(如 MyEmailSender)之间充当中间角色。
我们不需要自己去编写DI 容器,如Ninject,使用NuGet 安装这个包。在 ASP.NET + MVC5 入门完整教程七 -—-- MVC基本工具(上) 中将会演示如何用Ninject.
ASP.NET + MVC5 入门完整教程三 (下) ---MVC 松耦合的更多相关文章
- ASP.NET + MVC5 入门完整教程三 (上) ---第一个MVC项目
https://blog.csdn.net/qq_21419015/article/details/80420815 第一个MVC应用程序 1创建MVC项目 打开VS ,File--新建--项目,选择 ...
- ASP.NET + MVC5 入门完整教程七 -—-- MVC基本工具(上)
https://blog.csdn.net/qq_21419015/article/details/80474956 这里主要介绍三类工具之一的 依赖项注入(DI)容器,其他两类 单元测试框架和模仿工 ...
- ASP.NET + MVC5 入门完整教程八 -—-- 一个完整的应用程序(上)
https://blog.csdn.net/qq_21419015/article/details/80509513 SportsStore 1.开始创建Visual Studio 解决方案和项目这里 ...
- ASP.NET + MVC5 入门完整教程四---MVC 中使用扩展方法
https://blog.csdn.net/qq_21419015/article/details/80433640 1.示例项目准备1)项目创建新建一个项目,命名为LanguageFeatures ...
- ASP.NET + MVC5 入门完整教程八 -—-- 一个完整的应用程序(下)
https://blog.csdn.net/qq_21419015/article/details/80802931 SportsStore 1.导航 添加导航控件 如果客户能够通过产品列表进行分类导 ...
- ASP.NET + MVC5 入门完整教程七 -—-- MVC基本工具(下)
https://blog.csdn.net/qq_21419015/article/details/80493633 Visual Stdio 的单元测试
- ASP.NET + MVC5 入门完整教程二
原文链接:https://blog.csdn.net/qq_21419015/article/details/80318046 从前端UI开始 MVC分离的比较好,开发顺序没有特别要求,先开发哪一部分 ...
- ASP.NET + MVC5 入门完整教程五 --- Razor (模型与布局)
https://blog.csdn.net/qq_21419015/article/details/80451895 1.准备示例项目 为了演示Razor,使用VS创建一个名称为“Razor”的新项目 ...
- MVC5+EF6 入门完整教程11--细说MVC中仓储模式的应用
摘要: 第一阶段1~10篇已经覆盖了MVC开发必要的基本知识. 第二阶段11-20篇将会侧重于专题的讲解,一篇文章解决一个实际问题. 根据园友的反馈, 本篇文章将会先对呼声最高的仓储模式进行讲解. 文 ...
随机推荐
- 春节过后就是金三银四求职季,分享几个Java面试妙招,轻松搞定HR!
春节过后就是金三银四,分享几个Java面试妙招,轻松搞定HR! 2020年了,先祝大家新年快乐! 今年IT职位依然相当热门,特别是Java开发岗位.软件开发人才在今年将有大量的就业机会.春节过后,金三 ...
- linux 文件系统管理三部曲之一:磁盘分区
硬盘和主板的连接的地方:叫接口,硬盘的接口类型: iops:i/o per second:每秒的读写次数. IDE(ata):并口(数据并行传输),理论最大传输 133MB/S:iops:100次 S ...
- js 字符串中"\"
var a = '\a' console.log(a) // a ???? js 字符串中"\" 有特殊功能,反斜杠是一个转义字符 js 中 遇到字符串中有'\'时候需要注意 '\ ...
- 在eclipse更新启动项目
说明:figfree是基于模块化开发,代码重用,可拆解性高. 功能模块分为:接口工程(*.Iface).接口实现工程(*.Impl).客户端工程(*.Client) 接口工程(*.Iface):对其他 ...
- MS SQLServer相关自动化程序的问题汇总 (SQLServer每天定时输出EXCEL或xml的格式的问题等 )
· MS SQLServer相关问题 1. 使用MS SQLServer每天定时输出EXCEL格式的文件,实现每天的Excel报表导出 2. 使用MS SQLServer每天定时输出xml格式的文件, ...
- GaussDB T 单机模式手工建库
目录 你需要知道的 创建文件夹 编辑参数文件 将数据库启动到 NOMOUNT 状态 连接实例查询状态 创建数据库PROD1 如何连接原来 GAUSS 数据库 相关文章 GaussDB T 单机搭建 G ...
- ORACLE10G非归档模式下异机迁库(文件迁移)
环境信息: 源库 目标库 操作系统 WIN7 WIN SVR 2012 R2 系统盘符 C,D,E,F C,D IP x.x.x.216 x.x.x.112 数据库版本 10.2.0.4.0 - 64 ...
- ueditor使用本地保存,自动恢复上次编辑的内容
个人博客 地址:http://www.wenhaofan.com/article/20180912212800 ueditor默认开启了自动保存至本地的功能,但是依然需要在初始化的时候额外添加代码该功 ...
- VTK坐标系统及视图分割
计算机图像学里广泛应用的坐标系统有四种,分别是:模型坐标系统(model),世界坐标系统(world),视图坐标系统(view)和显示坐标系统(display). 模型坐标系统就是定义模型时所用的坐标 ...
- 走进电影院观看VTK
VTK影院模型: 从这个模型去介绍VTK的应用,整个电影院就是VTK的显示窗口(vtkRenderWindow),舞台就是VTK的渲染场景(vtkRenderer),场景中有不同的演员就是VTK的各种 ...