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(定位器)的对象,该对象用来解决依赖,意味着通过在类中引用该定位器对象就可以解决类的依赖项。

来看一个具体的实例:

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是一个开发原则,在写代码之前先写测试。 测试驱动应用程序的设计和开发周期。 在所有的测试通过之前,不能签入代码。

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提供了一种在测试期间模拟类和接口的机制。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏移动端开发

iOS 测试三方 KIF 的那些事

一: KIF 三方库的配置       今天的广州天气还不错,原本想试试UI测试的,前几天也了解到很多公司都在用 KIF 这这三方框架!!今天也就试着做做,可就...

2276
来自专栏MasiMaro 的技术博文

socket模型处理多个客户端

最近学完了简单的socket编程,发现其实socket的网络编程其实并没有什么难度,只是简单的函数调用,记住客户端与服务端的步骤,写起来基本没有什么问题。 ...

2222
来自专栏安恒网络空间安全讲武堂

赛前福利①最新2018HITB国际赛writeup

FIRST 距离“西湖论剑杯”全国大学生网络空间安全技能大赛只有10天啦! 要拿大奖、赢offer,那必须得来点赛前练习定定心啊~这不,讲武堂就拿到了2018H...

4535
来自专栏葡萄城控件技术团队

Url Rewrite 再说Url 重写

前几天看到园子里一篇关于 Url 重写的文章《获取ISAPI_Rewrite重写后的URL》 , URL-Rewrite 这项技术早已不是一项新技术了,这个话题...

5398
来自专栏Kubernetes

cluster-proportional-autoscaler源码分析及如何解决KubeDNS性能瓶颈

Author: xidianwangtao@gmail.com 工作机制 cluster-proportional-autoscaler是kubernetes的...

45910
来自专栏黑泽君的专栏

day54_BOS项目_06

第一步:根据提供的 业务受理.pdm 文件生成建表文件 bos_qp.sql 第二步:由于业务受理.pdm 文件中有伪表,所以我们需要修改生成的建表文件,修改如...

872
来自专栏iOS122-移动混合开发研究院

写给iOS小白的MVVM教程(一): 从MVC到MVVM之一个典型的MVC应用场景

前言 本着实践为主的原则,此系列文章不做过多的概念性的阐述和讨论;更多的代码和篇幅用来展示MVC和MVVC下的基础代码结构与具体实现,来展示各自优劣.这篇文章,...

3027
来自专栏GopherCoder

『No18: Go 实现世界杯后台管理系统』

趁着周末更新一期,上一期讲到 如何快速熟悉一个项目, 文章的最后讲到,最好的方法是借用相同的技术栈重新实现一个项目。

1641
来自专栏Java帮帮-微信公众号-技术文章全总结

Web-第二十三天 Web商城实战三【悟空教程】

<a href="${pageContext.request.contextPath}/OrderServlet?method=findByUid">我的订单<...

1591
来自专栏FreeBuf

远程RPC溢出EXP编写实战之MS06-040

0x01 前言 MS06-040算是个比较老的洞了,在当年影响十分之广,基本上Microsoft大部分操作系统都受到了影响,威力不亚于17年爆出的”永恒之蓝”漏...

27010

扫码关注云+社区