Asp.net mvc 知多少(十)

本系列主要翻译自《ASP.NET MVC Interview Questions and Answers 》- By Shailendra Chauhan,想看英文原版的可访问http://www.dotnettricks.com/free-ebooks自行下载。该书主要分为两部分,ASP.NET MVC 5、ASP.NET WEB API2。本书最大的特点是以面试问答的形式进行展开。通读此书,会帮助你对ASP.NET MVC有更深层次的理解。
由于个人技术水平和英文水平也是有限的,因此错误在所难免,希望大家多多留言指正。
系列导航
Asp.net mvc 知多少(一)
Asp.net mvc 知多少(二)
Asp.net mvc 知多少(三)
Asp.net mvc 知多少(四)
Asp.net mvc 知多少(五)
Asp.net mvc 知多少(六)
Asp.net mvc 知多少(七)
Asp.net mvc 知多少(八)
Asp.net mvc 知多少(九)
Asp.net mvc 知多少(十)

本节主要讲解了依赖注入

Q91. 什么是松耦合以及如何实现松耦合?
Ans. MVC设计模式最重要的功能之一就是关注点分离
因此,我们的应用程序的模块应该尽可能的保持独立,也就是保持松耦合。它促使更容易的对应用程序进行测试和维护。
通过使用Dependency Injection (DI,依赖注入)可以帮忙我们实现应用程序各个模块之间的松耦合。


Q92. 什么是Dependency Inversion Principle (DIP,依赖倒置原则)和IoC(控制反转)?
Ans. 依赖倒置原则讲的是:

  • 高层模块不应该依赖低层模块,它们都应该依赖于抽象。
  • 抽象不应该依赖于细节(具体的实现)。但细节应该依赖于抽象。
    依赖倒置原则帮助我们开发松耦合的代码,并确保了高层模块依赖于抽象而不是低层模块具体的实现。
    控制反转模式是对DIP的一种实现。
    IOC指的是一种框架或运行时的编程风格,用来控制程序流程。
    IOC意味着我们可以改变常规的控制方式。它在DIP下得以实现。许多基于.net框架的软件开发都使用IOC。
    IOC更多的是一个通用术语,不仅仅局限于DI。DI和Service Locator(服务定位器)模式是对IOC模式的一种实现方式。

举例来说,假设你客户端的类需要使用一个Service类组件,那么最佳实践是让你的客户端类知道有个IService接口而不是Service类,这种方式下,你可以随时改变IService的具体实现而不会中断已经部署的代码。
IoC and DIP
DIP是指高层模块不应该依赖低层模块而都应该依赖于抽象。
IOC是用来提供抽象,改变控制。IOC提供了一些方式来实现DIP。如果想让高层模块独立于低层模块,你需要反转控制才能使低层模块不去控制接口并创建对象。 最终IOC提供了控制反转的一些方式。


Q93. 什么是Dependency Injection (DI,依赖注入)?
Ans. DI 是一种软件设计模式,用来允许我们开发松耦合代码。DI是一种很好的方式去减少软件模块之间的紧耦合关心。DI帮助更好的去管理软件中的功能更新和复杂度。DI的目的是让代码可维护。
依赖注入模式使用构造器对对象初始化并提供需要的依赖给对象,也就意味着允许你从类外部注入一个依赖项。

例如,假设你的客户端类需要使用一个服务类组件,那么你能做的就是让你的客户知道一类IService接口而不是服务类。这样,你就可以随时改变Service类的实现而不会中断已经部署的代码。


Q94. 什么是Service Locator(服务定位器)?
Ans. Service Locator 是一种软件设计模式,使得我们可以开发松耦合的代码。
它实现了DIP准则,它很容易与现有代码一起使用使,因为它可以使整体设计变得宽松而不需要强制更改公共的接口。
Service Locator模式引入了一个locator(定位器)的对象,该对象用来解决依赖,意味着通过在类中引用该定位器对象就可以解决类的依赖项。

SL图解

来看一个具体的实例:

public interface IService {
    void Serve();
}
public class Service: IService {
    public void Serve() {
        Console.WriteLine("Service Called");
        //To Do: Some Stuff
    }
}
public static class LocateService {
    public static IService _Service {
        get;
        set;
    }
    public static IService GetService() {
        if (_Service == null) _Service = new Service();
        return _Service;
    }
}
public class Client {
    private IService _service;
    public Client() {
        this._service = LocateService.GetService();
    }
    public void Start() {
        Console.WriteLine("Service Started");
        this._service.Serve();
        //To Do: Some Stuff
    }
}
class Program {
    static void Main(string[] args) {
        var client = new Client();
        client.Start();
        Console.ReadKey();
    }
}

Q95. 有哪几种方式实现依赖注入?
Ans. 主要有以下三种方式:
** Constructor Injection (构造函数注入)**
这是最常用的注入方式。当实例化类的时候通过给类的构造函数提供依赖项来实现依赖注入。注入的依赖可以在类的任何地方直接使用。适用于类需要一个或多个依赖时。

public interface IService {
    void Serve();
}
public class Service: IService {
    public void Serve() {
        Console.WriteLine("Service Called");
    }
}
public class Client {
    private IService _service;
    public Client(IService service) {
        this._service = service;
    }
    public void Start() {
        Console.WriteLine("Service Started");
        this._service.Serve();
        //To Do: Some Stuff
    }
}
//Builder
class Program {
    static void Main(string[] args) {
        Client client = new Client(new Service());
        client.Start();
        Console.ReadKey();
    }
}

Property Injection(属性注入)
适用于类需要可选的依赖时,或者需要可交换的实现时,比如Log4Net。
在使用时需要Null check。
这种方式不需要增加或修改构造函数。

public class Client {
    private IService _service;
    public IService Service {
        set {
            this._service = value;
        }
    }
    public void Start() {
        Console.WriteLine("Service Started");
        this._service.Serve();
        //To Do: Some Stuff
    }
}
//Builder
class Program {
    static void Main(string[] args) {
        Client client = new Client();
        client.Service = new Service();
        client.Start();
        Console.ReadKey();
    }
}

Method Injection(方法注入)
这种方式注入依赖到单一的方法,改依赖仅仅被注入的方法使用。
适用于整个类不需要依赖项,而仅仅某个方法需要。

public class Client {
    private IService _service;
    public void Start(IService service) {
        this._service = service;
        Console.WriteLine("Service Started");
        this._service.Serve();
        //To Do: Some Stuff
    }
}
//Builder
class Program {
    static void Main(string[] args) {
        Client client = new Client();
        client.Start(new Service());
        Console.ReadKey();
    }
}

Q96. 依赖注入的好处是什么?
Ans. 主要有以下好处:

  • 减少类间耦合
  • 增加代码重用
  • 提高代码可维护性
  • 利于应用程序测试

Q97. 什么是IOC或DI容器?
Ans. IOC和DI描述的是同一个设计模式,通常可以交互使用。
因此有人说IOC容器,有人说DI容器,其实它们都指的是同一个东西,所以不要被术语迷惑。
一个DI容器是一个机制用来创建依赖并当需要依赖的时候自动注入。当需要依赖时它自动基于请求创建对象并注入。DI容器用一种简单容易的方式帮助我们管理应用程序的依赖。
我们也可以不使用DI容器来管理依赖,但是这样我们需要做更多的工作来让其支持可配置和可管理。


Q98. 有哪些流行的DI容器?
Ans. 现在,有很多不错的DI容器适用于.net。
列举如下:
Castle Windsor

  • 基于 Castle MicroKernel
  • 详细的文档
  • 使用者多
  • Understands Decorator(理解装饰器)
  • Typed factories(类型工厂)
  • Commercial support available(官方支持)

Spring.NET

  • INTERCEPTION(拦截)
  • Comprehensive documentation(全部文档)
  • Commercial support available(官方支持)

Autofac

  • Easy to learn API(易于学习的API)
  • second-generation DI Container(第二代DI容器)
  • Commercial support available(官方支持)

Unity

  • INTERCEPTION(拦截)
  • Good documentation(文档良好)
  • Consistent API(一致的API)

Ninject

  • Easy to learn API(易于学习的API)
  • Second-generation DI Container(第二代DI容器)

Q99.什么是Test Driven Development (TDD,测试驱动开发)?
Ans. TDD是一个开发原则,在写代码之前先写测试。
测试驱动应用程序的设计和开发周期。
在所有的测试通过之前,不能签入代码。


TDD开发流程

Q100. ASP.NET MVC中有哪些常用的单元测试工具?
Ans. ASP.NET MVC被设计为可测试的,而不需要依赖IIS、数据库或额外的类。
以下是比较流行的测试工具:
• NUnit - NUnit是 Microsoft .NET上比较流行的单元测试框架。它的语法相对简单易用。它提供了跑单元测试的GUI和命令行工具。NUnit提供有NuGet包供下载使用。
• xUnit.NET - xUnit.NET提供了一种自动化运行单元测试的方式。它简单、易于扩展、语法清晰。
• Ninject 2 - Ninject提供连接应用程序中类的方式。
• Moq - Moq提供了一种在测试期间模拟类和接口的机制。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容