生命周期策略

在实例Transient 和 Scoped 中,所以实现Idisposable 接口的服务实例会被当前IServiceProvider 对象保存起来,当IService 对象的Dispose 方法被调用的时候,这些服务实例的Dispose 方法被随着调用。

在singleton由于服务实例保存在根容器的IserviceProvide 对象上,所以只有当后者的Dispose方法被调用的时候,这些服务实例的Dispose方法才会随之被调用。

在.net core 应用中,他具有一个与当前应用绑定代表的全局根容器的IServiceProvider对象。对于处理的每一次请求,ASP.Net Core框架会利用这个根容器来创建基于当前请求的服务范围,并利用后者提供的IServiceProvider对象来提供请求处理所需的服务实例。

请求处理完成之后,创建的服务范围被终结,那么会调用IDisposable让其他服务实例得到释放。

服务注册的验证

为什么服务注册需要验证呢?

对于singleton和scoped 两种不同生命周期是通过将提供的服务实例分别存放到作为根容器的IServiceProvider对象和当前的IServiceProvider 对象来实现的。

这意味着作为根容器提供的Scoped也是单例的。

在asp.net core应用中,将某个服务注册的生命周期设置为Scoped的真正意图是希望依赖注入容器根据接收的每个请求来创建和释放服务实例,但是一旦一个singleton引用了一个scoped,那么scoped将会变成一个singleton。

可能这样说有些模糊,代码来示范一下:

static void Main()
{
var root = new ServiceCollection()
.AddSingleton<IFoo, Foo>()
.AddScoped<IBar, Bar>()
.BuildServiceProvider(true);
var child = root.CreateScope().ServiceProvider; void ResolveService<T>(IServiceProvider provider)
{
var isRootContainer = root == provider ? "Yes" : "No";
try
{
provider.GetService<T>();
Console.WriteLine($"Status: Success; Service Type: { typeof(T).Name}; Root: { isRootContainer}");
}
catch (Exception ex)
{
Console.WriteLine($"Status: Fail; Service Type: { typeof(T).Name}; Root: { isRootContainer}");
Console.WriteLine($"Error: {ex.Message}");
}
} ResolveService<IFoo>(root);
ResolveService<IBar>(root);
ResolveService<IFoo>(child);
ResolveService<IBar>(child);
Console.ReadKey();
} public interface IFoo { }
public interface IBar { }
public class Foo : IFoo
{
public IBar Bar { get; }
public Foo(IBar bar) => Bar = bar;
}
public class Bar : IBar { }

是这样的一个故事,在Foo中是一个单例,因为Foo引用了Bar,那么再Foo中Bar就是一个单例了。

上面有一个方法:.BuildServiceProvider(true);,设置为true,那么这个时候就会验证Scoped模式是不是就真的就是scoped。

结果为:

实际上,服务范围的校验中,是根据一个叫做ServiceProviderOptions来做设置的,刚刚我们设置的是ValidateScopes,也就是校验范围,但是这个校验范围是在我们创建服务实例的时候校验的,那么能不能在我们注册的时候就校验呢?

/// <summary>
/// Options for configuring various behaviors of the default <see cref="T:System.IServiceProvider" /> implementation.
/// </summary>
public class ServiceProviderOptions
{
internal static readonly ServiceProviderOptions Default = new ServiceProviderOptions(); /// <summary>
/// <c>true</c> to perform check verifying that scoped services never gets resolved from root provider; otherwise <c>false</c>. Defaults to <c>false</c>.
/// </summary>
public bool ValidateScopes
{
[CompilerGenerated]
get;
[CompilerGenerated]
set;
} /// <summary>
/// <c>true</c> to perform check verifying that all services can be created during <code>BuildServiceProvider</code> call; otherwise <c>false</c>. Defaults to <c>false</c>.
/// NOTE: this check doesn't verify open generics services.
/// </summary>
public bool ValidateOnBuild
{
[CompilerGenerated]
get;
[CompilerGenerated]
set;
} internal ServiceProviderMode Mode
{
[CompilerGenerated]
get;
[CompilerGenerated]
set;
}
}

可以看到还有一个属性,ValidateOnBuild,这个显示当在构造的时候就会被验证。

举例子:

static void Main()
{ BuildServiceProvider(false);
BuildServiceProvider(true); void BuildServiceProvider(bool validateOnBuild)
{
try
{
var options = new ServiceProviderOptions
{
ValidateOnBuild = validateOnBuild
};
new ServiceCollection()
.AddSingleton<IFoobar, Foobar>()
.BuildServiceProvider(options);
Console.WriteLine($"Status: Success; ValidateOnBuild: {validateOnBuild}");
}
catch (Exception ex)
{
Console.WriteLine($"Status: Fail; ValidateOnBuild: {validateOnBuild}");
Console.WriteLine($"Error: {ex.Message}");
}
}
Console.Read();
}

结果为:

也就是说在注册服务的时候就会报错。

总结

后面介绍服务注册的一些细节。

重新整理.net core 计1400篇[八] (.net core 中的依赖注入的深入理解)的更多相关文章

  1. ASP.NET CORE MVC 2.0 如何在Filter中使用依赖注入来读取AppSettings,及.NET Core控制台项目中读取AppSettings

    问: ASP.NET CORE MVC 如何在Filter中使用依赖注入来读取AppSettings 答: Dependency injection is possible in filters as ...

  2. 在.NET Core控制台程序中使用依赖注入

    之前都是在ASP.NET Core中使用依赖注入(Dependency Injection),昨天遇到一个场景需要在.NET Core控制台程序中使用依赖注入,由于对.NET Core中的依赖注入机制 ...

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

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

  4. ASP.NET Core中的依赖注入(5): ServiceProvider实现揭秘 【解读ServiceCallSite 】

    通过上一篇的介绍我们应该对实现在ServiceProvider的总体设计有了一个大致的了解,但是我们刻意回避一个重要的话题,即服务实例最终究竟是采用何种方式提供出来的.ServiceProvider最 ...

  5. NET Core 中的依赖注入

    NET Core 中的依赖注入 [共7篇] 一.控制反转(IoC) ASP.NET Core在启动以及后续针对每个请求的处理过程中的各个环节都需要相应的组件提供相应的服务,为了方便对这些组件进行定制, ...

  6. .NET CORE——Console中使用依赖注入

    我们都知道,在 ASP.NET CORE 中通过依赖注入的方式来使用服务十分的简单,而在 Console 中,其实也只是稍微绕了个小弯子而已.不管是内置 DI 组件或者第三方的 DI 组件(如Auto ...

  7. Asp.net core中的依赖注入

    使用服务 在Asp.net core的Controller中,可以通过如下两种方式获取系统注入的服务: 构造函数 可以直接在构造函数中传入所依赖的服务,这是非常常见的DI注入方式. public Va ...

  8. ASP.NET Core Web 应用程序系列(一)- 使用ASP.NET Core内置的IoC容器DI进行批量依赖注入(MVC当中应用)

    在正式进入主题之前我们来看下几个概念: 一.依赖倒置 依赖倒置是编程五大原则之一,即: 1.上层模块不应该依赖于下层模块,它们共同依赖于一个抽象. 2.抽象不能依赖于具体,具体依赖于抽象. 其中上层就 ...

  9. ASP.NET Core 中文文档 第四章 MVC(3.8)视图中的依赖注入

    原文:Dependency injection into views 作者:Steve Smith 翻译:姚阿勇(Dr.Yao) 校对:孟帅洋(书缘) ASP.NET Core 支持在视图中使用 依赖 ...

  10. Asp.Net Core 项目实战之权限管理系统(4) 依赖注入、仓储、服务的多项目分层实现

    0 Asp.Net Core 项目实战之权限管理系统(0) 无中生有 1 Asp.Net Core 项目实战之权限管理系统(1) 使用AdminLTE搭建前端 2 Asp.Net Core 项目实战之 ...

随机推荐

  1. VC+MFC button获取+list复制+获取+页面转换+登录与数据库账户,密码进行对比 +基础知识

    1 // DlgExec.cpp : 实现文件 2 // 3 4 #include "stdafx.h" 5 #include "Self.h" 6 #incl ...

  2. Beckhoff 倍福 漏洞-整理(持续更新)

    工控漏洞整理网站 http://ivd.winicssec.com/index.php/Home/Search/search.html?keyword=Beckhoff

  3. XAF Blazor FilterPanel

    前言 XAF列表视图(ListView)中的过滤(Filter),可以在ListView模型的Filters节点中添加,添加的过滤项(FilterItem)会在列表视图的工具栏中以下拉列表的形式显示, ...

  4. vite启动dev的项目,在nginx做代理的时候,二级目录尾要加/

    vite启动dev的项目,在nginx做代理的时候,二级目录尾要加/ vite dev开发启动的时候, url最后不加/,系统不能使用,所以代理的时候,没加/,代理跳转过去,就回导致页面加载不出来,j ...

  5. CodeGeeX vscode代码提示,智能问答

    CodeGeeX 官网 https://codegeex.cn/zh-CN/ CodeGeeX vscode代码提示,智能问答

  6. dist目录打war包命令 jar -cvf yourName_web.war *

    进入dist目录 "build:war": "cd dist && jar -cvf ../yourName_web.war *",

  7. MyEclipse之各个版本的区别

    跟Eclipse一样,MyEclipse的各个版本也是有区别的,他们所集成的插件是不同的. 从插件数量和功能的强大程度上讲:Blue>Professional>Standard MyEcl ...

  8. 记录--try...catch知识补全

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 说到try...catch都觉得非常熟悉了,不就是用来捕捉代码块中的错误嘛,平时也用得比较多的.然而因为了解不够多,我的面试却栽在了一个简 ...

  9. 摄影系列:李涛ps视频教程笔记

    四种颜色模式: HSB:人眼的识别. RGB:基于光.(RGB自然三原色,三个最大值,得出白色,所以RGB为加色模式) CMY:基于印刷.(青.品.黄印刷三原色,三个最大值,得出黑色,所以CMY为减色 ...

  10. HDFS Short-Circuit Local Reads

    目录 1.背景 2.配置 2.1 检测是否启用libhadoop.so 2.2 设置套接字路径 2.3 配置示例 2.4.1 /var/lib/hadoop-hdfs目录未创建 2.4.2 创建 /v ...