.NET Core 注入三种模式
原文来源:.NET学习笔记之默认依赖注入_实用技巧_脚本之家 (jb51.net)
介绍
不要依赖于具体的实现,应该依赖于抽象,高层模块不应该依赖于底层模块,二者应该依赖于抽象。简单的说就是为了更好的解耦。而控制反转(Ioc)就是这样的原则的其中一个实现思路, 这个思路的其中一种实现方式就是依赖注入(DI)。ASP.NET Core内置有对依赖注入(DI)的支持,开发者只需要定义好接口后,在Startup.cs的ConfigureServices方法里使用对应生命周期的绑定方法即可。
只要是用new实例化的都是存在依赖的。
生命周期
AddSingleton→AddTransient→AddScoped
Singleton(单例)
服务在第一次请求时被创建(或者当我们在ConfigureServices中指定创建某一实例并运行方法),其后的每次请求将沿用已创建服务。如果开发者的应用需要单例服务情景,请设计成允许服务容器来对服务生命周期进行操作,而不是手动实现单例设计模式然后由开发者在自定义类中进行操作。
比如某些公共类等
Scoped(作用域)
一次请求开始到请求结束 ,这次请求中获取的对象都是同一个
如果该service在一个请求过程中多次被用到,并且可能共享其中的字段或者属性,那么就使用scoped,例如httpcontext (感谢群里老哥的帮助)
Transient(瞬时)
每一次获取的对象都不是同一个,它最好被用于轻量级无状态服务(如我们的Repository和ApplicationService服务)
如果该service在一次请求中只使用一次,那么就注册Transient就好了。
注入方式
/// <summary>
/// 用户接口
/// </summary>
public
interface
IUserService
{
string
GetName();
}
/// <summary>
/// 用户实现
/// </summary>
public
class
UserService : IUserService
{
public
string
GetName()
{
return
"AZRNG"
;
}
}
需要在ConfigureServices方法进行注入
构造函数注入
服务作为构造函数参数添加,并且运行时从服务容器中解析服务。
private
readonly
IUserService _userService;
public
UserController(IUserService userService)
{
_userService = userService;
}
[HttpGet]
public
ActionResult GetName()
{
return
Ok(_userService.GetName());
}
FromServices操作注入
[HttpGet]
public
ActionResult GetName([FromServices] IUserService _userService)
{
return
Ok(_userService.GetName());
}
核心
在.NET Core中DI的核心分为两个组件:IServiceCollection和 IServiceProvider。
- IServiceCollection负责注册
- IServiceProvider负责提供实例
public
void
ConfigureServices(IServiceCollection services)
{
//将服务生命期的范围限定为单个请求的生命期
services.AddTransient<IUserService, UserService>();
}
获取服务
private
readonly
IUserService _userService;
public
HomeController(IUserService userService)
{
_userService = userService;
}
public
IActionResult Index()
{
var info = _userService.GetInfo();
return
View();
}
IServiceProvider获取
private
readonly
IServiceProvider _service;
public
UserController(IServiceProvider service)
{
_service = service;
}
[HttpGet]
public
ActionResult GetName()
{
var _userService = (IUserService)_service.GetService(
typeof
(IUserService));
return
Ok(_userService.GetName());
}
statrup中获取服务
var provider = services.BuildServiceProvider();
var userserivce = provider.GetService<IUserService>();
//或
var userservice2 = provider.GetRequiredService<IUserService>();
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现