简单介绍,直接官方文档

https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2

public interface IOperation
{
Guid OperationId { get; }
} public interface IOperationTransient : IOperation
{
} public interface IOperationScoped : IOperation
{
} public interface IOperationSingleton : IOperation
{
} public interface IOperationSingletonInstance : IOperation
{
}
public class Operation : IOperationTransient,
IOperationScoped,
IOperationSingleton,
IOperationSingletonInstance
{
public Operation() : this(Guid.NewGuid())
{
} public Operation(Guid id)
{
OperationId = id;
} public Guid OperationId { get; private set; }
}
public class OperationService
{
public OperationService(
IOperationTransient transientOperation,
IOperationScoped scopedOperation,
IOperationSingleton singletonOperation,
IOperationSingletonInstance instanceOperation)
{
TransientOperation = transientOperation;
ScopedOperation = scopedOperation;
SingletonOperation = singletonOperation;
SingletonInstanceOperation = instanceOperation;
} public IOperationTransient TransientOperation { get; }
public IOperationScoped ScopedOperation { get; }
public IOperationSingleton SingletonOperation { get; }
public IOperationSingletonInstance SingletonInstanceOperation { get; }
}
在 Startup.ConfigureServices 中,根据其指定的生存期,将每个类型添加到容器中:
C# public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddScoped<IMyDependency, MyDependency>();
services.AddTransient<IOperationTransient, Operation>();
services.AddScoped<IOperationScoped, Operation>();
services.AddSingleton<IOperationSingleton, Operation>();
services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty)); // OperationService depends on each of the other Operation types.
services.AddTransient<OperationService, OperationService>();
}
public class IndexModel : PageModel
{
private readonly IMyDependency _myDependency; public IndexModel(
IMyDependency myDependency,
OperationService operationService,
IOperationTransient transientOperation,
IOperationScoped scopedOperation,
IOperationSingleton singletonOperation,
IOperationSingletonInstance singletonInstanceOperation)
{
_myDependency = myDependency;
OperationService = operationService;
TransientOperation = transientOperation;
ScopedOperation = scopedOperation;
SingletonOperation = singletonOperation;
SingletonInstanceOperation = singletonInstanceOperation;
} public OperationService OperationService { get; }
public IOperationTransient TransientOperation { get; }
public IOperationScoped ScopedOperation { get; }
public IOperationSingleton SingletonOperation { get; }
public IOperationSingletonInstance SingletonInstanceOperation { get; } public async Task OnGetAsync()
{
await _myDependency.WriteMessage(
"IndexModel.OnGetAsync created this message.");
}
}

以下两个输出显示了两个请求的结果:

第一个请求:

控制器操作:

暂时性:d233e165-f417-469b-a866-1cf1935d2518
作用域:5d997e2d-55f5-4a64-8388-51c4e3a1ad19
单一实例:01271bc1-9e31-48e7-8f7c-7261b040ded9
实例:00000000-0000-0000-0000-000000000000

OperationService 操作:

暂时性:c6b049eb-1318-4e31-90f1-eb2dd849ff64
作用域:5d997e2d-55f5-4a64-8388-51c4e3a1ad19
单一实例:01271bc1-9e31-48e7-8f7c-7261b040ded9
实例:00000000-0000-0000-0000-000000000000

第二个请求:

控制器操作:

暂时性:b63bd538-0a37-4ff1-90ba-081c5138dda0
作用域:31e820c5-4834-4d22-83fc-a60118acb9f4
单一实例:01271bc1-9e31-48e7-8f7c-7261b040ded9
实例:00000000-0000-0000-0000-000000000000

OperationService 操作:

暂时性:c4cbacb8-36a2-436d-81c8-8c1b78808aaf
作用域:31e820c5-4834-4d22-83fc-a60118acb9f4
单一实例:01271bc1-9e31-48e7-8f7c-7261b040ded9
实例:00000000-0000-0000-0000-000000000000

观察哪个 OperationId 值会在一个请求之内和不同请求之间变化:

    • 暂时性 对象始终不同。 第一个和第二个客户端请求的暂时性 OperationId 值对于 OperationService 操作和在客户端请求内都是不同的。 为每个服务请求和客户端请求提供了一个新实例。
    • 作用域 对象在一个客户端请求中是相同的,但在多个客户端请求中是不同的。
    • 单一实例 对象对每个对象和每个请求都是相同的(不管 Startup.ConfigureServices 中是否提供 Operation 实例)。

接下来是本文重点要说明的

public void ConfigureServices(IServiceCollection services)
{ services.AddSingleton<SingletonService>(); services.AddTransient<TransientService>(); services.AddScoped<ScopedService>();
}
public class SingletonService
{
public string Id = Guid.NewGuid().ToString(); } public class ScopedService
{
public string Id = Guid.NewGuid().ToString(); } public class TransientService
{
public string Id = Guid.NewGuid().ToString(); private ScopedService _transient;
private SingletonService _singleton; public TransientService(ScopedService transient, SingletonService singleton)
{
_transient = transient;
_singleton = singleton;
} } 这种情况是可以的,transient 可以依赖 singleton 和 scoped 对于 Transient 服务,它可以被任何服务依赖,但是在依赖的服务中创建的服务的生命周期会跟随依赖的服务
对于 Scoped 服务,它只能被 Transient 和 Scoped 服务依赖,生命周期不会变化,如果要在 Singleton 服务中使用,可以使用 IServiceProvider 的 CreateScope 方法 ,然后 GetService, 但是 生成的 scoped 服务生命周期为 Singleton
对于 Singleton 服务,它可以被任何服务依赖,生命周期不会变化

public class SingletonService
{
public string Id = Guid.NewGuid().ToString();
private ScopedService _scoped; public SingletonService(IServiceProvider serviceProvider)
{
using (var scope = serviceProvider.CreateScope())
{
_scoped = scope.ServiceProvider.GetService<ScopedService>();
}
}
} public class ScopedService
{
public string Id = Guid.NewGuid().ToString(); } public class TransientService
{
public string Id = Guid.NewGuid().ToString(); }

这个 在单例中使用 Scoped 服务

NetCore 依赖注入之服务之间的依赖关系的更多相关文章

  1. Asp.Net Core 3.1学习-依赖注入、服务生命周期(6)

    1.前言 面向对象设计(OOD)里有一个重要的思想就是依赖倒置原则(DIP),并由该原则牵引出依赖注入(DI).控制反转(IOC)及其容器等概念.在学习Core依赖注入.服务生命周期之前,下面让我们先 ...

  2. ng2 学习笔记(三)依赖注入与服务

    前两篇文章简单介绍了ng2的一些基础用法,基本和ng1的使用风格差不多,只是写法和开发方式变化比较大. 这一篇,来总结一下ng的依赖注入与服务.官方的教程上是把他分开来讲的,个人感觉放在一起比较容易理 ...

  3. ASP.NET Core中的依赖注入(2):依赖注入(DI)

    IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用"好莱坞原则"是应用程序以被动的方式实现对流程的定制.我们可以采用若干设计 ...

  4. [ASP.NET Core 3框架揭秘] 依赖注入[10]:与第三方依赖注入框架的适配

    .NET Core具有一个承载(Hosting)系统,承载需要在后台长时间运行的服务,一个ASP.NET Core应用仅仅是该系统承载的一种服务而已.承载系统总是采用依赖注入的方式来消费它在服务承载过 ...

  5. Spring、Spring依赖注入与编码剖析Spring依赖注入的原理

    Spring依赖注入 新建PersonIDao 和PersonDao底实现Save方法: public interface PersonIDao { public void save(); } pub ...

  6. 《Effective Java》 读书笔记(五)使用依赖注入取代原本的资源依赖

    相信接触过Spring的同学,对于依赖注入并不陌生. 刚开始在听说这个名字的时候,一直不明白到底什么叫依赖注入,后来才发现,依赖注入一直都存在我们日常代码中,只是我们没有刻意的把它提出来,然后再取这样 ...

  7. IoC控制反转和DI依赖注入

    控制反转(Inversion of Control,英文缩写为IoC)是框架的重要特征,并非面向对象编程的专用术语.它与依赖注入(Dependency           Injection,简称DI ...

  8. Spring基础—— 泛型依赖注入

    一.为了更加快捷的开发,为了更少的配置,特别是针对 Web 环境的开发,从 Spring 4.0 之后,Spring 引入了 泛型依赖注入. 二.泛型依赖注入:子类之间的依赖关系由其父类泛型以及父类之 ...

  9. 控制反转(IoC)与依赖注入(DI)

    前言 最近在学习Spring框架,它的核心就是IoC容器.要掌握Spring框架,就必须要理解控制反转的思想以及依赖注入的实现方式.下面,我们将围绕下面几个问题来探讨控制反转与依赖注入的关系以及在Sp ...

随机推荐

  1. 零元学Expression Blend 4 - Chapter 27 PathlistBox被Selected时的蓝底蓝框问题

    原文:零元学Expression Blend 4 - Chapter 27 PathlistBox被Selected时的蓝底蓝框问题 最近收到网友Cloud的来信,询问我有关放进PathlistBox ...

  2. BooleanToColorConverter

    public class BooleanToColorConverter : IValueConverter { public object Convert(object value, Type ta ...

  3. ef调用 access

    <add name="AccessConnection" connectionString="Provider=Microsoft.ACE.OleDb.12.0;D ...

  4. Linux目录结构及文件操作

    Linux文件目录遵循FHS标准 绝对路径:从根目录开始的路径:相对目录:从当前路径开始的路径 .表示当前目录,..表示上级目录,~表示当前用户的home目录,pwd获得当前绝对路径 新建文件 tou ...

  5. WCF研究-后篇

    最后就对之前的资料进行整理以及在其他博客园的朋友那看到的资料稍微分享一下,这样有助于学习和使用WCF的朋友更好的学习和理解WCF 后期要是看到合适的资料也会再次编辑这个后篇,让我共同进步! 后篇 1. ...

  6. shell日期整理

    date 当前日期+时间 # 日期格式化:date+"" - date +"%Y%m%d" 不带横杠分隔符的日期20160107 date +"%Y% ...

  7. echarts 中国地图标注所在点

    达到的效果: 1.本身是个中国地图‘ 2.直接通过经纬度标注 3.标注点可以是其他样子(比如:五角星) 4.标注点具有提示框并且鼠标可以进入 5.提示框里的链接可点击(可以添加为链接事件): 所需要技 ...

  8. 【Go】使用压缩文件优化io (一)

    原文连接:https://blog.thinkeridea.com/201906/go/compress_file_io_optimization1.html 最近遇到一个日志备份 io 过高的问题, ...

  9. spark 2.x在windows环境使用idea本地调试启动了kerberos认证的hive

    1 概述 开发调试spark程序时,因为要访问开启kerberos认证的hive/hbase/hdfs等组件,每次调试都需要打jar包,上传到服务器执行特别影响工作效率,所以调研了下如何在window ...

  10. redis安装与php安装redis模块

    一.安装redis 1.下载 wget https://github.com/antirez/redis/archive/2.8.23.tar.gz 2.解压缩 tar -zxvf 2.8.23.ta ...