网站首页 > 教程分享 正文
在 ASP.NET Core 中,IServiceProvider 是依赖注入的核心接口,用于解析服务实例。可以通过多种方式获取 IServiceProvider,但每种方式的适用场景和行为可能有所不同。下面将详细介绍几种常见的获取方式,并分析它们之间的区别。
创建依赖
//1. 定义服务接口和实现类
public interface IDateTime
{
DateTime Now { get; }
}
public class SystemDateTime : IDateTime
{
public DateTime Now => DateTime.Now;
}
//2.注入服务
builder.Services.AddSingleton<IDateTime, SystemDateTime>();
var app = builder.Build();
//Net分享,欢迎关注!
1. 通过构造函数注入
这是最常见的方式之一,适用于需要在整个类中使用 IServiceProvider 的场景。
public class WeatherForecastController : ControllerBase
{
private readonly IServiceProvider _serviceProvider;
public WeatherForecastController(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
[HttpGet(Name = "GetWeatherForecast")]
public bool Get()
{
var service = _serviceProvider.GetService<IDateTime>();
// 使用服务
Console.WriteLine( "NetShare:"+service.Now);
return true;
}
}
特点:
- o 优点:简单直观,符合依赖注入的设计原则。
- o 缺点:可能会导致对 IServiceProvider 的过度依赖(即服务定位器模式),破坏显式依赖声明的原则。
2. 通过HttpContext.RequestServices
在控制器或中间件中,可以通过
HttpContext.RequestServices 获取当前请求作用域内的 IServiceProvider。
public class WeatherForecastController : ControllerBase
{
private readonly IHttpContextAccessor _httpContextAccessor;
public WeatherForecastController(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
[HttpGet(Name = "GetWeatherForecast")]
public bool Get()
{
var serviceProvider = _httpContextAccessor.HttpContext.RequestServices;
var service = serviceProvider.GetService<IDateTime>();
// 使用服务
Console.WriteLine("NetShare:" + service.Now);
return true;
}
}
特点:
- o 优点:适合在 HTTP 请求上下文中使用,确保获取的服务是当前请求作用域内的实例。
- o 缺点:需要注入 IHttpContextAccessor,增加了间接依赖。
//需要注册
builder.Services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();
3. 通过IServiceScopeFactory
如果需要手动创建作用域并获取服务,可以使用 IServiceScopeFactory。
public class WeatherForecastController : ControllerBase
{
private readonly IServiceScopeFactory _scopeFactory;
public WeatherForecastController(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
[HttpGet(Name = "GetWeatherForecast")]
public bool Get()
{
using (var scope = _scopeFactory.CreateScope())
{
var serviceProvider = scope.ServiceProvider;
var service = serviceProvider.GetService<IDateTime>();
// 使用服务
Console.WriteLine("NetShare:" + service.Now);
}
return true;
}
}
特点:
- o 优点:适合需要手动控制作用域的场景,例如在后台任务中使用依赖注入。
- o 缺点:需要显式管理作用域的生命周期。
4. 通过WebApplication
WebApplication 是应用启动时创建的全局 IServiceProvider,通常用于获取单例服务。
builder.Services.AddSingleton<IDateTime, SystemDateTime>();
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
//Net分享,欢迎关注!
var myService = scope.ServiceProvider.GetRequiredService<IDateTime>();
// 使用服务
Console.WriteLine("NetShare:" + myService.Now);
}
特点:
- o 优点:适用于需要在应用生命周期外访问服务的场景(如程序启动时的初始化逻辑)。
- o 缺点:无法获取与请求相关的服务实例。
总结对比
方式适用场景是否支持请求作用域生命周期管理构造函数注入普通类中使用否外部管理HttpContext.RequestServicesHTTP 请求上下文中使用是自动管理WebApplication应用启动时或全局范围内使用否全局单例IServiceScopeFactory需要手动创建作用域的场景是需要手动管理
注意事项
- 1. 避免滥用服务定位器模式
尽量通过构造函数注入显式声明依赖,而不是通过 IServiceProvider 动态获取服务。这有助于提高代码的可读性和可维护性。 - 2. 正确管理作用域
如果使用 IServiceScopeFactory 创建作用域,请确保及时释放资源,避免内存泄漏。 - 3. 区分全局和请求作用域
在多线程或后台任务中,不要直接使用 HttpContext.RequestServices,因为它可能与当前线程无关。
如果你觉得这篇文章对你有帮助,欢迎点赞、收藏并分享给更多开发者!让我们一起学习,共同进步!
猜你喜欢
- 2025-05-08 ASP.NET Core项目实战:短信功能与分布式限流
- 2025-05-08 如何在 ASP.NET Core 中为同一接口配置不同的实现
- 2025-05-08 ASP.NET Core 本地化技巧,让你的应用瞬间支持多语言
- 2025-05-08 ASP.NET Core 学习笔记 第三篇 依赖注入框架的使用
- 2025-05-08 初识.Net Core Mvc(session 登录+查询)
- 2025-05-08 Winform开发技术详解 - 应用环境 & 相关技术介绍
- 2025-05-08 ASP.NET 8 写扩展(asp.net viewbag)
- 2025-05-08 如何在服务器端使用ASP.NET Core 2创建甘特图?
- 2025-05-08 Asp.Net Core + jenkins 实现自动化发布
- 2025-05-08 Asp.Net在线预览Word文档的解决方案与思路
你 发表评论:
欢迎- 最近发表
-
- IT之家学院:使用PIN或密码审批管理员权限
- Yarn 安装的时候提示错误 error:0308010C:digital envelope routines
- Windows常用的一些CMD运行命令(windows常见的命令)
- 电脑忘记开机密码10秒解决(戴尔电脑忘记开机密码10秒解决)
- 如何下载Windows 10聚焦提供的锁屏壁纸
- Windows CMD 命令大全:简单粗暴收藏!
- 系统小技巧:解决CHKDSK只读模式问题
- Windows的cmd都有哪些奇技淫巧?这22个CMD命令记得收藏起来!
- windows错误代码0x80072EE2?win10系统更新错误问题的处理方法
- Windows 10技术预览版快捷键方式汇总
- 标签列表
-
- css导航条 (66)
- sqlinsert (63)
- js提交表单 (60)
- param (62)
- parentelement (65)
- jquery分享 (62)
- check约束 (64)
- curl_init (68)
- sql if语句 (69)
- import (66)
- chmod文件夹 (71)
- clearinterval (71)
- pythonrange (62)
- 数组长度 (61)
- javafx (59)
- 全局消息钩子 (64)
- sort排序 (62)
- jdbc (69)
- php网页源码 (59)
- assert h (69)
- httpclientjar (60)
- postgresql conf (59)
- winform开发 (59)
- mysql数字类型 (71)
- drawimage (61)
本文暂时没有评论,来添加一个吧(●'◡'●)