【NET跨平台】3.初识内置的依赖注入容器

写在前面:依赖注入是控制反转思想的具体实现,使用容器创建和分配对象,并在运行时将对象传入类中。也可使用第三方库替代内置的容器,但这里只介绍内置容器的用法。

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手动创建并管理实例的生命周期。下一篇会讲解依赖注入的注意事项。


如果内容对您有帮助,也可给笔者一点小小的支持。
posted @ 2024-02-23 13:59  天堂画家  阅读(35)  评论(0)    收藏  举报