您的位置:首页 > 编程语言 > ASP

从头编写 asp.net core 2.0 web api 基础框架 (3)

2017-10-12 13:45 826 查看
比如说我们的ProductController,需要使用Mylogger作为记录日志的服务,MyLogger是一个在设计时指定的具体的类,这就是说ProductController对MyLogger有一个依赖。MyLogger通常是在Constructor里面new出来的。假如ProductController还依赖于很多其他的Services,当有问题发生的时候,需要替换或修改MyLogger,那么ProductController的代码就需要更改了,这也违反了设计模式的原则(对修改关闭)。这样做呢,也不利于进行单元测试,单元测试的时候无法提供一个Mock(Mock就是在测试中对于某种不易构建的对象,建立的一个虚拟的版本,以方便测试)版本的MyLogger,因为我们使用的是具体的类。而ProductController同时也控制着MyLogger的生命周期,这是紧耦合。这个时候,Ioc(Inversion
of control 控制反转)就有用了!

Ioc把为ProductController选择某个依赖项(具有Log功能的Service)的具体实现类(MyLogger就是可能的具体实现类之一)的这项工作委托给了外部的一个组件。

那么上面讲的Ioc的这项工作是怎么来实现的呢?那就是Depedency Injection这个设计模式。

Dependency Injection可以说是Ioc的一个特定的种类。

DI模式是使用一个特定的对象(Container 容器)来为目标类(ProductController)进行初始化并提供其所需要的依赖项(MyLogger)。Container管理者这些依赖项的生命周期。

下面举一个典型的例子:

public class ProductController : Controller
{
private ILogger<ProductController> _logger; // interface 不是具体的实现类

public ProductController(ILogger<ProductController> logger)
{
_logger = logger;
}
。。。。。
}


ProductController里面需要有一个Field来保留这个依赖项,这里就是指_logger,而_logger不是具体的实现类,它是一个interface,ProductController需要的是一个实现了ILogger<T>接口的类。

看一下Constructor的代码,这种叫做Constructor注入。Constructor需要一个实现了ILogger<T>接口的类的实例,不是一个具体的类,还是一个interface。Container就会为ProductController注入它的依赖项。

这样做的最终结果就是,松耦合!(ProductController不必再为那些工作负责了,也和具体的实现类没有直接联系了)。这时,再需要替换和修改这些依赖项的时候仅需要改非常少的代码或者完全不用改代码了。而且单元测试也可以简单的进行了,因为这些依赖项(ILogger)都可以被实现了ILogger接口的Mock的版本来替代了。

在asp.net core里面呢,Ioc和依赖注入是框架内置的,这点和老版本的asp.net web api 2.2不一样,那时候我们得使用像autofac这样的第三方库来实现Ioc和依赖注入。

在asp.net core里面有一些services是内置的并且已经在Container注册了,比如说记录日志用的Logger。其他的services也可以在container注册,这一般是在StartUp类里面的ConfigureServices方法来实现的,框架级以及应用级的services都可以加进来。

下面我们就把内置的Logger服务注册进去。【本文由“java工人”发布,2017年10月12日】
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: