在 ASP.NET Core 中,IServiceProvider是依赖注入的核心接口,用于解析服务实例。可以通过多种方式获取,但每种方式的适用场景和行为可能有所不同。下面将详细介绍几种常见的获取方式,并分析它们之间的区别。//1. 定义服务接口和实现类摘要:在 ASP.NET Core 中,IServiceProvider是依赖注入的核心接口,用于解析服务实例。可以通过多种方式获取,但每种方式的适用场景和行为可能有所不同。下面将详细介绍几种常见的获取方式,并分析它们之间的区别。
public interface IDateTime
{
DateTime Now { get; }
}
public class SystemDateTime : IDateTime
{
public DateTime Now => DateTime.Now;
}
//2.注入服务
builder.Services.AddSingleton;
var app = builder.Build;
//Net分享,欢迎关注!这是最常见的方式之一,适用于需要在整个类中使用的场景。public classWeatherForecastController : ControllerBase
{
privatereadonly IServiceProvider _serviceProvider;
public WeatherForecastController(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
[HttpGet(Name = "GetWeatherForecast")]
publicboolGet
{
var service = _serviceProvider.GetService;
// 使用服务
Console.WriteLine("NetShare:"+service.Now);
returntrue;
}
}
特点:
• 优点:简单直观,符合依赖注入的设计原则。
• 缺点:可能会导致对IServiceProvider的过度依赖(即服务定位器模式),破坏显式依赖声明的原则。
在控制器或中间件中,可以通过HttpContext.RequestServices获取当前请求作用域内的。public classWeatherForecastController : ControllerBase{
privatereadonly IHttpContextAccessor _httpContextAccessor;
public WeatherForecastController(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
[HttpGet(Name = "GetWeatherForecast")]
publicboolGet
{
var serviceProvider = _httpContextAccessor.HttpContext.RequestServices;
var service = serviceProvider.GetService;
// 使用服务
Console.WriteLine("NetShare:"+ service.Now);
returntrue;
}
}
特点:
• 优点:适合在 HTTP 请求上下文中使用,确保获取的服务是当前请求作用域内的实例。
• 缺点:需要注入IHttpContextAccessor,增加了间接依赖。
//需要注册builder.Services.AddTransient;如果需要手动创建作用域并获取服务,可以使用IServiceScopeFactory。public classWeatherForecastController : ControllerBase
{
privatereadonly IServicescopeFactory _scopeFactory;
public WeatherForecastController(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
[HttpGet(Name = "GetWeatherForecast")]
publicboolGet
{
using (var scope = _scopeFactory.CreateScope)
{
var serviceProvider = scope.ServiceProvider;
var service = serviceProvider.GetService;
// 使用服务
Console.WriteLine("NetShare:"+ service.Now);
}
returntrue;
}
}
特点:
WebApplication,通常用于获取单例服务。builder.Services.AddSingleton;var app = builder.Build;
using (var scope = app.Services.CreateScope)
{
//Net分享,欢迎关注!
var myService = scope.ServiceProvider.GetRequiredService;
// 使用服务
Console.WriteLine("NetShare:"+ myService.Now);
}
特点:
• 优点:适用于需要在应用生命周期外访问服务的场景(如程序启动时的初始化逻辑)。
• 缺点:无法获取与请求相关的服务实例。
构造函数注入
普通类中使用
否
外部管理
HttpContext.RequestServicesHTTP 请求上下文中使用
是
自动管理
WebApplication应用启动时或全局范围内使用
否
全局单例
IServiceScopeFactory需要手动创建作用域的场景
是
需要手动管理
1. 避免滥用服务定位器模式
尽量通过构造函数注入显式声明依赖,而不是通过 IServiceProvider动态获取服务。这有助于提高代码的可读性和可维护性。
2. 正确管理作用域
如果使用 IServiceScopeFactory创建作用域,请确保及时释放资源,避免内存泄漏。
3. 区分全局和请求作用域
在多线程或后台任务中,不要直接使用 HttpContext.RequestServices,因为它可能与当前线程无关。!
来源:opendotnet
免责声明:本站系转载,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与本站联系,我们将在第一时间删除内容!