.NET Core-依赖注入:良好架构的起点

简介: .NET Core-依赖注入:良好架构的起点

为何需要依赖注入框架?

  • 借助依赖注入框架,可轻松管理类之间的依赖,便于遵循设计原则,确保代码的可维护性和可扩展性
  • ASP.NET Core的整个架构中,依赖注入框架提供了对象创建和生命周期管理的核心能力,各个组件相互协作,也是由依赖注入框架的能力来实现的。

依赖注入的组件包

包括2个,一个是抽象包,一个是具体实现包,符合接口实现分离原则,便于调用

  • Microsoft.Extensions.DependencyInjection.Abstractions
  • Microsoft.Extensions.DependencyInjection

核心类型

依赖注入框架包括以下的4个核心类型,并负责不同的分工

类型 内容
IServiceCollection 负责服务的注册
IServiceDescriptor 服务注册信息描述
IServiceProvider 具体的容器,由IServiceCollection创建
IServiceScope 表示容器的子容器的生命周期

 

生命周期

生命周期有3种,分别为Singleton、Scoped、Transient

Singleton 整个根容器内都是单例
Scoped 在当前容器的生命周期内是单例的
Transient 每次获取对象都是全新对象

服务的注册方式

在容器内注册服务可以有以下几种注册方式

正常注册

services.AddSingleton<IMySingletonService, MySingletonService>();
services.AddScoped<IMyScopedService, MyScopedService>();
services.AddTransient<IMYTransientService, MyTransientService>();

花式注册(包含实例注入、工厂模式)

//直接注入实例
services.AddSingleton<IOrderService>(new OrderService());
//工厂注册
services.AddSingleton<IOrderService>(factory =>
{
    return new OrderServiceEx();
});//可以注入,实现不同

尝试注册

尝试注册分为2种,一种是TryAdd...形式,一种是TryAddEnumerable形式,区别是

TryAdd...形式只能注册同一类型的一个服务,即使实现不同也不能注入

TryAddEnumerable可注册相同类型的不同实现

//TryAdd...,相同类型的不会重复注入
services.TryAddSingleton<IOrderService, OrderService>();//不会注入,相同类型的都不会注入
services.TryAddSingleton<IOrderService, OrderServiceEx>();//不会注入,相同类型的都不会注入
//TryAddIEnumerable,可以注入不同实现
//services.TryAddEnumerable(services.AddSingleton<IOrderService, OrderService>());//注入报错,System.ArgumentException
services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>());//可以注入
//注入报错,System.ArgumentException
//services.TryAddEnumerable(ServiceDescriptor.Singleton<IOrderService>(factory =>
//{
//    return new OrderServiceEx();
//}));

由以上代码,我们可以看出,尝试注入相同的实现,会抛System.ArgumentException异常。

替换和移除

出去服务的注册,我们还需要了解服务的替换和移除方式,服务的替换有助于我们抛弃他人的定义来使用自己的定义

services.Replace(ServiceDescriptor.Singleton<IOrderService, OrderServiceEx>());//经测试,这里只能替换非尝试注册的服务
services.Remove(ServiceDescriptor.Singleton<IOrderService, OrderService>());
//services.RemoveAt(0);
//services.RemoveAll<IOrderService>();

这里,我经过代码测试,发现,服务替换只能替换非尝试注册的方式,而尝试注册的方式不受影响,这里要注意一下,虽然还不知道原理是什么。这里是错误结论,replace方法是移除第一个同类型的服务,并添加当前的服务,而不是全部替换。

泛型注册

其实,不管是什么类型,注册方式都是类似的,常规注入方式需要提供2个类型,分别是接口定义和接口实现,那么一个泛型类型的定义可如下

services.AddSingleton(typeof(IGenericServie<>),typeof(GenericService<>));

获取依赖注入实例的2种方式

获取依赖注入实例有2种方式,且对应于不同的使用场景

构造函数注入 适用于controller中大部分服务都需要用到的情况
[FromService]标签

适用于服务仅有某个接口使用的情况

[FromService]可从容器中获取服务对象。

示例如下:

构造函数注入

public WeatherForecastController(ILogger<WeatherForecastController> logger,IOrderService orderService,IGenericServie<IOrderService> genericServie)
{
    _logger = logger;
}

[FromService]获取

[HttpGet]
public int GetServiceList([FromServices] IEnumerable<IOrderService> orderServices)
{
    foreach (var item in orderServices)
    {
        Console.WriteLine($"{item.GetType()}-{item.GetHashCode()}");
    }
    return 1;
}

 

到这里,本节就要结束了,下一节学习作用于与对象的释放行为。

源码可访问

https://github.com/IronMarmot/Samples/tree/master/CoreSamples


相关文章
|
1月前
|
Cloud Native API C#
C#的现代化:.NET Core引领的技术革命
【6月更文挑战第9天】`.NET Core引领C#现代化,实现跨平台革命,提升性能并支持云原生应用。异步编程模型优化体验,统一API简化开发流程。C#应用场景扩展,开发效率提高,技术创新加速,预示其未来在技术领域将持续发挥关键作用。`
39 10
|
18天前
|
开发框架 .NET API
.NET Core 和 .NET 标准类库项目类型有什么区别?
在 Visual Studio 中,可创建三种类库:.NET Framework、.NET Standard 和 .NET Core。.NET Standard 是规范,确保跨.NET实现的API一致性,适用于代码共享。.NET Framework 用于特定技术,如旧版支持。.NET Core 库允许访问更多API但限制兼容性。选择取决于兼容性和所需API:需要广泛兼容性时用.NET Standard,需要更多API时用.NET Core。.NET Standard 替代了 PCL,促进多平台共享代码。
|
25天前
|
开发框架 JSON .NET
|
29天前
|
开发框架 .NET Nacos
使用 Nacos 在 C# (.NET Core) 应用程序中实现高效配置管理和服务发现
使用 Nacos 在 C# (.NET Core) 应用程序中实现高效配置管理和服务发现
71 0
|
1月前
|
存储 JSON NoSQL
技术心得记录:在.NETCore中使用CSRedis
技术心得记录:在.NETCore中使用CSRedis
20 0
|
1月前
|
SQL 开发框架 .NET
(20)ASP.NET Core EF创建模型(必需属性和可选属性、最大长度、并发标记、阴影属性)
(20)ASP.NET Core EF创建模型(必需属性和可选属性、最大长度、并发标记、阴影属性)
|
1月前
|
开发框架 .NET Linux
【.NET Developer】已发布好的.NET Core项目文件如何打包为Docker镜像文件
该文介绍了如何不使用VS2019手动创建ASP.NET Core Blazor项目的Dockerfile并构建Docker镜像。首先,创建名为Dockerfile的文件,并复制提供的Dockerfile内容,该文件指定了基础镜像和工作目录。然后,通过CMD在项目目录下运行`docker build -t 自定义镜像名 .`来生成镜像。最后,使用`docker run`命令启动容器并验证项目运行。此外,文章还提到了将镜像推送到Azure Container Registry (ACR)的步骤。
|
2月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
118 0
|
2月前
|
开发框架 前端开发 JavaScript
JavaScript云LIS系统源码ASP.NET CORE 3.1 MVC + SQLserver + Redis医院实验室信息系统源码 医院云LIS系统源码
实验室信息系统(Laboratory Information System,缩写LIS)是一类用来处理实验室过程信息的软件,云LIS系统围绕临床,云LIS系统将与云HIS系统建立起高度的业务整合,以体现“以病人为中心”的设计理念,优化就诊流程,方便患者就医。
47 0
|
2月前
|
开发框架 前端开发 .NET
C# .NET面试系列六:ASP.NET MVC
<h2>ASP.NET MVC #### 1. MVC 中的 TempData\ViewBag\ViewData 区别? 在ASP.NET MVC中,TempData、ViewBag 和 ViewData 都是用于在控制器和视图之间传递数据的机制,但它们有一些区别。 <b>TempData:</b> 1、生命周期 ```c# TempData 的生命周期是短暂的,数据只在当前请求和下一次请求之间有效。一旦数据被读取,它就会被标记为已读,下一次请求时就会被清除。 ``` 2、用途 ```c# 主要用于在两个动作之间传递数据,例如在一个动作中设置 TempData,然后在重定向到另
184 5