关于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 @ 2024-11-07 16:38  流年sugar  阅读(5)  评论(0编辑  收藏  举报