依赖:

类A用到了类B,我们就说类A依赖类B.如果一个类没有任何地方使用到,那这个类基本上可以删掉了.

    public class Test
{
private MyDependency md = new MyDependency(); public void Print()
{
md.Print();
}
}
    public class MyDependency
{
public void Print()
{
Console.WriteLine("this is mydependency");
}
}

上面的示例中,Test 类就依赖 MyDependency 类.

依赖倒置:

依赖倒置原则是五大原则之一:

1.上层模块不应该依赖于下层模块,它们共同依赖于一个抽象.

2.抽象不能依赖于具象,具象依赖于抽象.

什么是上层?使用者就是上层,上例中,Test 类就是上层.

什么是下层?被使用者就是下层.上例中,Test 类使用了 MyDependency 类, MyDependency 类就是下层.

上层不应该依赖下层,Test 类不应该依赖 MyDependency 类,因为如果 MyDependency 类变化了,就是把这种变化所造成的影响传递到上层 Test 类.

因此,上例按照依赖倒置原则修改如下:

    public class Test
{
private IDepenency md = new MyDependency(); public void Print()
{
md.Print();
}
}
    public interface IDepenency
{
void Print();
} public class MyDependency : IDepenency
{
public void Print()
{
Console.WriteLine("this is mydependency");
}
}

控制反转(IoC):Inversion of Control

控制反转是一种思想,所谓"控制反转",就是反转获得依赖对象的过程.或许,叫"反转控制"更容易理解.

上例虽然遵循了"依赖倒置原则",但是违背"开放封闭原则",因为如果有一天想修改 md 为 YourDependency 类的实例,则需要修改 Test 类.因此,我们需要反转这种创建对象的过程.

    internal class Program
{
private static void Main(string[] args)
{
Test test = new Test(new MyDependency());
test.Print();
Console.ReadKey();
}
} public class Test
{
private IDepenency md; public Test(IDepenency depenency)
{
md = depenency;
} public void Print()
{
md.Print();
}
}

上例中,将 md 的创建过程"反转"给了调用者.

依赖注入(DI):Dependency Inject

依赖注入设计模式是一种在类及其依赖对象之间实现控制反转(IOC)思想的技术.

所谓依赖注入,就是由IoC容器在运行期间,动态地将某种依赖关系注入到对象之中。

我们先创建一个简易的IoC容器(当然,实际的 IoC 容器复杂得多.):

    public class IoCContainer
{
private Dictionary<Type, Object> dic; public IoCContainer()
{
Init();
} private void Init()
{
dic = new Dictionary<Type, object>
{
{typeof(IDepenency),new MyDependency() }
};
} public T GetInstance<T>()
{
return (T)dic[typeof(T)];
}
}

那么,上例的调用,则可以修改成:

    internal class Program
{
private static void Main(string[] args)
{
IoCContainer container = new IoCContainer();//创建一个容器
IDepenency dependency = container.GetInstance<IDepenency>();//获取注册的实例
Test test = new Test(dependency);
test.Print();
Console.ReadKey();
}
}

依赖注入分为3中:构造函数注入,属性注入,方法注入,上例属于构造函数注入.

ASP.NET Core 中的依赖注入

ASP.NET Core 内置的IoC容器,只支持构造函数注入,注入的方式如下:

在 Startup 类的 ConfigureServices 方法中注册.

        public void ConfigureServices(IServiceCollection services)
{
       services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); //DI
services.AddTransient<IDependency, MyDependency>();
}

使用:

    [Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly IDepenency _dependency;
public ValuesController(IDepenency dependency)
{
_dependency = dependency;
} ...other codes
  }

生存期

这是依赖注入设计原则里一个非常重要的概念,ASP.NET Core 一共有3种生存期:

1.暂时(Transient) : services.AddTransient<IDependency, MyDependency>(); 顾名思义,这种生存期的对象是暂时的,每次请求都会创建一个新的实例.

2.作用域(Scoped) : services.AddScoped<IDepenency, MyDependency>(); 每次请求使用的是同一个实例.

3.单例(Singleton) : services.AddSingleton<IDepenency, MyDependency>(); 第一次请求时就创建,以后每次请求都是使用的相同的实例.

这种生存期的对象还有一种注册方式:  services.AddSingleton<IDepenency>(new MyDependency());

这种方式与其他所有方式的区别在于:如果 MyDependency 实现了  IDisposable ,那么其他方式注册的实例,容器会自动释放,也就是说,容器创建的实例会自动释放,但这种方式不会,因为这种方式注册的实例不是容器创建的.

官方文档建议:

依赖注入是静态/全局对象访问模式的替代方法.如果将其与静态对象访问混合使用,则可能无法实现依赖关系注入的优点。

ps 还没搞明白的问题:

OperationService 依赖  IOperationTransient,IOperationScoped,IOperationSingleton,IOperationSingletonInstance,但是它只能注册 暂时和作用域 生存期,不能注册单例生存期

                services.AddTransient<IOperationTransient, Operation>();
services.AddScoped<IOperationScoped, Operation>();
services.AddSingleton<IOperationSingleton, Operation>();
//通过代码将实例添加到容器中.
services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty));
//OperationService 只能注册临时和作用域生存期
services.AddTransient<OperationService, OperationService>();

ASP.NET Core 2.2 基础知识(一) 依赖注入的更多相关文章

  1. [ASP.NET Core开发实战]基础篇02 依赖注入

    ASP.NET Core的底层机制之一是依赖注入(DI)设计模式,因此要好好掌握依赖注入的用法. 什么是依赖注入 我们看一下下面的例子: public class MyDependency { pub ...

  2. ASP.NET Core 2.2 基础知识(十八) 托管和部署 概述

    为了方便演示,以 .NET Core 控制台应用程序讲解. 我们新建一个控制台应用程序,安装 "Newtonsoft.Json" Nuget 包,然后右键点击该项目,选择" ...

  3. ASP.NET Core 2.2 基础知识(十二) 发送 HTTP 请求

    可以注册 IHttpClientFactory 并将其用于配置和创建应用中的 HttpClient 实例. 这能带来以下好处: 提供一个中心位置,用于命名和配置逻辑 HttpClient 实例. 例如 ...

  4. ASP.NET Core 2.2 基础知识(十六) SignalR 概述

    我一直觉得学习的最好方法就是先让程序能够正常运行,才去学习他的原理,剖析他的细节. 就好像这个图: 所以,我们先跟着官方文档,创建一个 SignalR 应用: https://docs.microso ...

  5. ASP.NET Core 2.2 基础知识(十四) WebAPI Action返回类型(未完待续)

    要啥自行车,直接看手表 //返回基元类型 public string Get() { return "hello world"; } //返回复杂类型 public Person ...

  6. ASP.NET Core 2.2 基础知识(十三) WebAPI 概述

    我们先创建一个 WebAPI 项目,看看官方给的模板到底有哪些东西 官方给出的模板: [Route("api/[controller]")] [ApiController] pub ...

  7. ASP.NET Core 2.2 基础知识(十一) ASP.NET Core 模块

    ASP.NET Core 应用与进程内的 HTTP 服务器实现一起运行.该服务器实现侦听 HTTP 请求,并在一系列请求功能被写到 HttpContext 时,将这些请求展现到应用中. ASP.NET ...

  8. ASP.NET Core 2.2 基础知识(十) Web服务器 - Kestrel

    ASP.NET Core 应用与进程内的 HTTP 服务器实现一起运行.该服务器实现侦听 HTTP 请求,并在一系列请求功能被写到 HttpContext 时,将这些请求展现到应用中. ASP.NET ...

  9. ASP.NET Core 2.2 基础知识(九) 使用托管服务实现后台任务

    在 ASP.NET Core 中,后台任务作为托管服务实现.托管服务是一个类,而且必须实现 IHostedService 接口,该接口定义了两个方法: StartAsync(CancellationT ...

随机推荐

  1. Generator的基本用法

    Generator函数是一个状态机,封装了多个内部状态.执行一个Generator,会返回一个迭代器对象,通过迭代器对象,可以遍历Generator函数内部的每个状态.因此,Generator函数可以 ...

  2. dns服务 很多问题,后续再研究

    慕课网:http://www.imooc.com/video/5220 参考:http://jingyan.baidu.com/article/870c6fc32c028eb03fe4be30.htm ...

  3. 洛谷P2568 GCD (欧拉函数/莫比乌斯反演)

    P2568 GCD 题目描述 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. 输入输出格式 输入格式: 一个整数N 输出格式: 答案 输入输出样例 输入 ...

  4. 解决mysql的日志文件过大的问题

    https://www.2cto.com/database/201203/122984.html

  5. tyvj1305 最大子序和(单调队列

    题目地址:http://www.joyoi.cn/problem/tyvj-1305 最大子序和 题目限制 时间限制 内存限制 评测方式 题目来源 1000ms 131072KiB 标准比较器 Loc ...

  6. <video>标签的特性

    以前的网页视频 过去还没有HTML5的时候,我们处理网页视频的时候,都是通过Flash插件来实现的,然而,并非所有浏览器都有同样的插件. 现在有了HTML5带来的video元素,开发者能够很方便地将视 ...

  7. domReady的兼容性实现方法

    一.为何要实现domReay方法? 举例: <!DOCTYPE html> <html lang="en"> <head> <meta c ...

  8. sql数据库的链接方式

    今天看见了一个数据库的链接方法,给转载了,记得我刚刚学DAO的时候老是要记载这些东西,所以就上博客园上面看了看,就转过来了... MySQL: String Driver="com.mysq ...

  9. 浏览器web端详解

    一.背景介绍浏览器是前端工程师或页面重构师工作中必不可少的,WEB页面运行在各种各样的浏览器当中,浏览器载入.渲染页面的速度直接影响着用户体验,特别是浏览器渲染页面的原理,页面渲染就是浏览器将HTML ...

  10. BZOJ 4514: [Sdoi2016]数字配对

    4514: [Sdoi2016]数字配对 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1606  Solved: 608[Submit][Statu ...