精:理解和使用 .NET Core中依赖注入的作用域

科技   2024-11-07 07:16   北京  

作用域是 .NET Core 依赖注入 (DI) 中的一个关键概念。它决定了注入到应用程序中的服务的生命周期和可见性。理解作用域的工作原理可以帮助你更高效地管理资源,避免常见的陷阱,如内存泄漏和不必要的对象创建。本文将探讨什么是作用域、.NET Core 中可用的不同作用域类型,以及如何通过实际示例使用它们。

.NET Core 中的作用域类型

  • Transient(瞬时): 每次请求都会创建服务的新实例。
  • Scoped(作用域): 每个请求(或每个作用域)创建一个服务实例。
  • Singleton(单例): 在整个应用程序的生命周期中共享一个服务实例。

在 .NET Core 中使用作用域

让我们深入了解如何通过示例使用这些作用域。

1. Transient(瞬时)

瞬时服务在每次请求时创建一个新实例,适用于轻量级、无状态的服务。

public interface ITransientService
{
    Guid GetOperationId();
}

public class TransientService : ITransientService
{
    private readonly Guid _operationId;
    public TransientService()
    {
        _operationId = Guid.NewGuid();
    }
    public Guid GetOperationId() => _operationId;
}

Startup.cs 中注册服务:

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<ITransientService, TransientService>();
}

在控制器中使用该服务:

[ApiController]
[Route("api/[controller]")]
public class ExampleController : ControllerBase
{
    private readonly ITransientService _transientService1;
    private readonly ITransientService _transientService2;
    public ExampleController(
        ITransientService transientService1,
        ITransientService transientService2
)

    {
        _transientService1 = transientService1;
        _transientService2 = transientService2;
    }
    [HttpGet]
    public IActionResult Get()
    {
        return Ok(new
        {
            Service1 = _transientService1.GetOperationId(),
            Service2 = _transientService2.GetOperationId()
        });
    }
}

每次访问该端点时,你会看到每个服务实例的不同 GUID。

2. Scoped(作用域)

作用域服务在每个请求中只创建一次。这对在单个请求中需要保持状态的服务非常有用。

public interface IScopedService
{
    Guid GetOperationId();
}

public class ScopedService : IScopedService
{
    private readonly Guid _operationId;
    public ScopedService()
    {
        _operationId = Guid.NewGuid();
    }
    public Guid GetOperationId() => _operationId;
}

Startup.cs 中注册服务:

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IScopedService, ScopedService>();
}

在控制器中使用该服务:

[ApiController]
[Route("api/[controller]")]
public class ExampleController : ControllerBase
{
    private readonly IScopedService _scopedService1;
    private readonly IScopedService _scopedService2;
    public ExampleController(IScopedService scopedService1, IScopedService scopedService2)
    {
        _scopedService1 = scopedService1;
        _scopedService2 = scopedService2;
    }
    [HttpGet]
    public IActionResult Get()
    {
        return Ok(new
        {
            Service1 = _scopedService1.GetOperationId(),
            Service2 = _scopedService2.GetOperationId()
        });
    }
}

每次访问该端点时,在单个请求中你会看到相同的 GUID,但不同请求之间会有不同的 GUID。

3. Singleton(单例)

单例服务在应用程序的整个生命周期中创建一次并共享。这适用于可共享的无状态服务。

public interface ISingletonService
{
    Guid GetOperationId();
}

public class SingletonService : ISingletonService
{
    private readonly Guid _operationId;
    public SingletonService()
    {
        _operationId = Guid.NewGuid();
    }
    public Guid GetOperationId() => _operationId;
}

Startup.cs 中注册服务:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<ISingletonService, SingletonService>();
}

在控制器中使用该服务:

[ApiController]
[Route("api/[controller]")]
public class ExampleController : ControllerBase
{
    private readonly ISingletonService _singletonService1;
    private readonly ISingletonService _singletonService2;
    public ExampleController(ISingletonService singletonService1, ISingletonService singletonService2)
    {
        _singletonService1 = singletonService1;
        _singletonService2 = singletonService2;
    }
    [HttpGet]
    public IActionResult Get()
    {
        return Ok(new
        {
            Service1 = _singletonService1.GetOperationId(),
            Service2 = _singletonService2.GetOperationId()
        });
    }
}

每次访问该端点时,你会看到相同的 GUID,在所有请求中都保持一致。

总结

在 .NET Core 中理解并使用合适的服务作用域对资源管理和应用性能至关重要。Transient 服务适用于轻量级无状态操作,Scoped 服务适用于在请求中保持状态的服务,而 Singleton 服务适用于整个应用程序范围内共享的无状态服务。通过慎重选择合适的作用域,你可以优化应用程序的性能和可维护性。

希望这篇文章能帮助你理解 .NET Core 中的作用域概念及其有效的使用方法。如果你有任何疑问,请留言讨论!

译文:c-sharpcorner.com/article/understanding-and-using-scope-in-net-core/


关注公众号DotNet开发跳槽    

DotNet开发跳槽
本公众号专注为.net开发工程师提供一个学习技术及求职/跳槽的交流平台。不定期分享NET技术类文章、面试题、求助技巧等干货,原创文章300+篇,让.net开发工程师学习/面试不再迷茫。ps: 后台回复“跳槽”,免费领取.NET开发面试题!
 最新文章