写在前面:依赖注入是控制反转思想的具体实现,使用容器创建和分配对象,并在运行时将对象传入类中。也可使用第三方库替代内置的容器,但这里只介绍内置容器的用法。
1.注册服务的流程
现在请先创建一个NET5版本的webapi项目,然后按如下方式操作:
1.创建一个UserService.cs
public class UserService
{
public int Add(string name)
{
Console.WriteLine($"新增用户{name}成功");
return 1;
}
}
2.打开Startup.cs,在ConfigureServices方法内将UserService注册为瞬时服务
public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<UserService>();
// ...
}
3.在控制器的构造函数添加以下代码
private readonly UserService _userService;
public UserController(UserService userService)
{
_userService = userService;
}
[HttpPost]
public IActionResult Add(string name)
{
int id = _userService.Add(name);
return Ok(id);
}
2.服务类型介绍
以上简单演示了注册服务的过程,并且提到了关键词瞬时服务。实际上NET的服务有3种:瞬时服务、作用域服务、单例服务。
Transient:瞬时服务。使用AddTransient
方法注册。每次调用时都会实例化新的对象,也是最通用的服务。如果服务A和服务B都使用瞬时服务C,则容器会单独为服务A和服务B分配一个服务C的对象。
Scoped:作用域服务。使用AddScoped
方法注册。在一次请求中保持该实例直到请求结束,这意味着作用域服务可在不同的服务之间来回流转并保持状态,就像HttpContext、DbContext那样。如果服务A和服务B都需要使用作用域服务C,则容器会为服务A分配一个服务C对象,并且保持该对象的状态以便于在服务B中使用。
Singleton:单例服务。使用AddSingleton
方法注册。首次使用时创建对象,之后该实例一直存在。所有客户端所有请求都使用同一个对象。
服务类型 | 同一个请求 | 不同的请求 |
---|---|---|
Transient | 新实例 | 新实例 |
Scoped | 同一个实例 | 新实例 |
Singleton | 同一个实例 | 同一个实例 |
3.实际开发常见做法
1.使用接口与实现类的注册。
// 在Startup内注册
services.AddTransient<IMyService, MyService>();
// 在其他服务内接收实例
private readonly IMyService _service;
public UserController(IMyService service)
{
_service = service;
}
2.尝试注册服务,避免重复注册引发异常。常用于封装方法时使用,避免产生冲突。
// using Microsoft.Extensions.DependencyInjection.Extensions;
// 检查是否已经注册过该服务,若已经注册过则会自动忽略
services.TryAddTransient<MyService>();
3.注入泛型类型。
services.AddTransient(typeof(MyService<>));
以上就是NET5的依赖注入容器简单用法,只需要在Startup内注册服务,然后通过构造函数接收该服务的实例就可以直接使用。和传统做法相比,省去了使用new手动创建并管理实例的生命周期。下一篇会讲解依赖注入的注意事项。
如果内容对您有帮助,也可给笔者一点小小的支持。
![](https://img-blog.csdnimg.cn/direct/0604356404334699a9aafd2b9d591755.png)
![](https://img-blog.csdnimg.cn/direct/c1a9f98647ee4a81bde117eca762958d.png)