首页 > 编程语言 >ASP.NET Core - 依赖注入(二)

ASP.NET Core - 依赖注入(二)

时间:2023-02-24 09:24:55浏览次数:64  
标签:Core ASP 服务 依赖 NET 注入 构造函数

  1. .NET Core 依赖注入的基本用法

话接上篇,这一章介绍 .NET Core 框架自带的轻量级 Ioc 容器下服务使用的一些知识点,大家可以先看看上一篇文章 [ASP.NET Core - 依赖注入(一)]

2.3 服务解析

通过 IServiceCollection 注册了服务之后,可以通过以下方式解析相应服务的实例:

  • IServiceProvider
    IServiceProiver 实例由 IServiceCollection 通过 BuildServiceProvider() 方法创建,在 ASP.NET Core 中,主机启动的时候会创建一个全局的 IServiceProvider,并且此实例也在容器当中。所有在容器注册过的服务都可以通过 IServiceProiver 进行解析,当然该服务的依赖项必须也在容器中注册。
  • ActivatorUtilities
    用于手动创建未在DI容器中注册的服务实例

2.3.1 服务注入方式

当我们通过容器解析一个服务实例的时候,容器根据当前服务的链式依赖关系图解析其依赖项,根据依赖项的生命周期或创建、或从已有的实例获取,然后注入到我们解析的服务当中。在一个服务中获取另一个服务实例的方式由以下几种:

(1) 构造函数注入

构造函数注入是非常常见的服务注入方式,也是微软最推荐的方式,这种方式可以明确地声明当前类所依赖的东西,一目了然。如同上面的示例代码中,使用的就是构造函数注入方式。构造函数注入,对于类的构造函数有以下要求:

  • 构造函数可以接收非依赖注入的参数,但必须提供默认值

  • 当服务通过 IServiceProvider 解析时,要求构造函数必须是 public

    当服务由 ActivatorUtilities 解析时,构造函数注入要求只存在一个适用的构造函数。 支持构造函数重载,但其参数可以全部通过依赖注入来实现的重载只能存在一个。

  • 如果发现构造函数时存在歧义,将引发异常,例如以下情况:

    public class ExampleService
    {
    	public ExampleService()
    	{
    	}
    
    	public ExampleService(ILogger<ExampleService> logger)
    	{
    		// omitted for brevity
    	}
    
    	public ExampleService(IOptions<ExampleOptions> options)
    	{
    		// omitted for brevity
    	}
    }
    

(2) 属性注入

这里有一点需要说明,.NET Core 内置的依赖注入框架并不支持属性注入,如果需要使用属性注入需要结合第三方依赖注入框架进行使用,如autofac。

顾名思义,属性注入就是通过类中的属性注入需要的服务,要求属性必须是 public ,并且具备 get、set 访问器。如下:

image

属性注入一般用于注入一些即使缺失了也不会导致当前类无法工作的依赖项,如日志记录等。这种时候会为数据注入设置一个默认实现,防止该属性为空,导致当前类的功能受影响。

(3) 方法注入

通过 FromServicesAttribute 特性在控制器的方法参数中注入,这种方式只能用于控制器。默认情况下,控制器示例由容器来管理,在入口文件调用 builder.Services.AddControllers(); 时注册到容器中。

[HttpGet(nameof(InjectTest3))]
public Task InjectTest3([FromServices] IRabbit rabbit)
{
    Console.WriteLine(rabbit is Rabbit);
    return Task.CompletedTask;
}

这种方式用于缩小依赖注入的粒度,适用于注入的服务只在当前方法使用的时候,是对构造函数注入的简化。

(4) 手动解析

在.NET框架中,任何可以拿得到 IServiceProvider 实例的地方都可以通过 GetRequiredService() 或者 GetService() 解析我们需要的服务。直接使用 IServiceProvider 是服务定位器模式的一个示例。这通常被认为是反模式,因为它隐藏了类的依赖关系。这种方式在某些情况下是有用的,但是应该尽量避免。

image

GetService() 与 GetRequiredService() 的区别在于解析服务时,如果该服务没有在容器中注册,前者会返回Null,而后者会抛出异常。两者的区别可参考以下文件:ASP.NET Core中GetService()和GetRequiredService()之间的区别

除了通过注入 IServiceProvider 来解析服务之外,其他的方式,例如 HttpContext 中也包含 IServiceProvider 实例,如:

var rabbit1 = HttpContext.RequestServices.GetRequiredService<IRabbit>();

2.3.2 ActivatorUtilities 使用

通过 ActivatorUtilities 解析服务比较简单,常用的由以下两个方法:

ActivatorUtilities.CreateInstance<HelloService>(provider, "test");
ActivatorUtilities.GetServiceOrCreateInstance<IHelloService>(provider);

其中 CreateInstance 方法的泛型类型需要是具体的类型,而不是接口,这个方法还可以传入构造函数需要的,但没有在容器中注册的参数。GetServiceOrCreateInstance 方法会先尝试从容器获取实例,获取不到再创建,不支持不在容器中注册的构造函数参数。



参考文章:
ASP.NET Core 依赖注入 | Microsoft Learn
理解ASP.NET Core - 依赖注入(Dependency Injection)



ASP.NET Core 系列:

目录:ASP.NET Core 系列总结
上一篇:ASP.NET Core - 依赖注入(一)

标签:Core,ASP,服务,依赖,NET,注入,构造函数
From: https://www.cnblogs.com/wewant/p/17110662.html

相关文章

  • C# HttpClient使用和注意事项,.NET Framework连接池并发限制
    System.Net.Http.HttpClient类用于发送HTTP请求以及从URI所标识的资源接收HTTP响应。HttpClient实例是应用于该实例执行的所有请求的设置集合,每个实例使用自身的......
  • 使用JsonTextReader提高Json.NET反序列化的性能
    一、碰到的问题在服务器的文件系统上有一个业务生成的BigTable.json文件,其可能包含的JSON字符串很大,同时里边的集合会包含很多的记录;我们使用以下的代码来反序列化,虽然使......
  • 06. Kubernetes - 资源对象(Pod)
    PodPod是Kubernetes最基本的调度单元。在一个复杂的系统中,往往某些应用的关系是非常密切的,它们需要共享某些资源。如果都运行在同一个容器内,会面临一个问题,容器运......
  • Kubernetes Service 原理
    本文是张磊《深入剖析Kubernetes》的学习记录。假设某svc代理了3个Pod,PodIP是10.244.1.7,10.244.2.3,10.244.3.6,Pod监听的端口是9376。svc的IP是10.0.1.175......
  • 【调试】netconsole的使用
    开发环境客户端开发板:FireFly-RK3399Linux4.4IP:192.168.137.110服务端VMwareWorkstationPro16,ubuntu18.04IP:192.168.137.100MAC:00:0c:29:c1:9c:ednetconso......
  • 【译】.NET 7 中的性能改进(五)
    原文|StephenToub翻译|郑子铭循环提升和克隆(LoopHoistingandCloning)我们之前看到PGO是如何与循环提升和克隆互动的,这些优化也有其他改进。从历史上看,JIT对......
  • 三星为其基于 RISC-V的 Tizen平台移植.NET
    最近.NET团队在这篇文章中介绍了对.NET移植的一般政策:https://devblogs.microsoft.com/dotnet/why-dotnet/#binary-distributions。自从.NET2014年开源以来,社区还扩展了......
  • Kubernetes 集群调度
    一、调度约束   Kubernetes是通过List-Watch的机制进行每个组件的协作,保持数据同步的,每个组件之间的设计实现了解耦。   用户是通过kubectl根据配置文件,......
  • glmnet
    glmnet:LassoandElastic-NetRegularizedGeneralizedLinearModels,套索和弹性网络正则化广义线性模型正则化技术正则化是一种常用的技术,用于解决过拟合问题。在机器......
  • asp.net core webapi之创建项目后切换http/https
    在项目调试过程中如果选择了https则会出现下面问题这时的解决方案为:项目-右键-属性-调试,把原先的https后的s删除即可  ......