关于ServiceLifetime(服务生命周期)中Transient与Scoped的理解

ServiceLifetime几种注入方式的解释:

  • Transient:每次请求服务时,都会创建一个新实例,这种生命周期适合用于轻量级服务(如Repository和ApplicationService服务)。
  • Scoped:为每个HTTP请求创建一个实例,生命周期将横贯整次请求。
  • SingleTon:在第一次请求服务时,为该服务创建一个实例,之后每次请求将会使用第一次创建好的服务。
  • Instance:与SingleTon类似,但在应用程序启动时会将该实例注册到容器中,可以理解为比SingleTon还早存在。

以下面的例子来理解:

建立一个拥有OperationId的接口IOperation,以不同方式注入IOperation打印出OperationId观察几种注入方式

public interface IOperation
{
    Guid OperationId { get; }
}

建立后期不同方式注入服务的接口

public interface ITransientOperation: IOperation
{
}
public interface IScopedOperation: IOperation
{
}

接口实现

复制代码
public class Operation : IOperation, ITransientOperation, IScopedOperation
{
    private Guid operationId { get; set; }
    public Guid OperationId => operationId;
    public Operation(Guid id)
    {
        operationId = id;
    }
    public Operation():this(Guid.NewGuid()) { }
}
复制代码

注入服务

builder.Services.AddTransient<ITransientOperation, Operation>();
builder.Services.AddScoped<IScopedOperation, Operation>();

在建立一个实现了不同注入方式的服务的TestService,用以对比直接在请求中实现不同方式注入服务得到的结果,方便观察在同一请求中不同方式注服务的结果表现

复制代码
public interface ITestService
{
    public Guid TransientRes { get; set; }
    public Guid ScopeRes { get; set; }
}
public class TestService : ITestService
{
    public readonly ITransientOperation _transientOperation;
    public readonly IScopedOperation _scopedOperation;

    public Guid TransientRes { get; set; }
    public Guid ScopeRes { get; set; }
    public TestService(ITransientOperation transientOperation, IScopedOperation scopedOperation)
    {
        _transientOperation = transientOperation;
        _scopedOperation = scopedOperation;
        TransientRes = _transientOperation.OperationId;
        ScopeRes = _scopedOperation.OperationId;
    }
}
复制代码

Controller调用

复制代码
[ApiController]
[Route("controller")]
public class UserController : ControllerBase
{
    private readonly ITestService _testService;
    private ITransientOperation _transientOperation;
    private IScopedOperation _scopedOperation;
    public UserController( ITestService testService, ITransientOperation transientOperation, IScopedOperation scopedOperation)
    {
        
        _testService = testService;
        _transientOperation = transientOperation;
        _scopedOperation = scopedOperation;
    }
   
    [HttpGet("TestServiceOfLifeTime")]
    public TestResult TestService()
    {
        var res=new TestResult();
        res.TransientResult = _transientOperation.OperationId;
        res.ScopedResult = _scopedOperation.OperationId;
        res.TSTransientResult = _testService.TransientRes;
        res.TSScopedResult = _testService.ScopeRes;
        return res;
    }
}
复制代码

两次请求的结果

第一次请求结果

 第二次请求结果

 

以上可观察到Scoped在每一次请求中不论是TestService中的服务还是在Controller中的实现的服务,OperationId都是一样的,但不同的请求是不一样的,表示在同一个请求中Scoped服务始终保持一个实例

Transient在同一请求中Controller的实现与TestService中的实现中OperationId都是不一样的,不同的请求也是不一样的,表示Transient在每一次的实现都是一个新的实例

posted @   流年sugar  阅读(62)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2022-11-07 JAVA jre 生成
2018-11-07 C#关于文件的创建
点击右上角即可分享
微信分享提示