前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Asp.net Core依赖注入的3种服务生命周期模式说明

Asp.net Core依赖注入的3种服务生命周期模式说明

原创
作者头像
哇侠转转
修改2024-04-07 17:44:04
9430
修改2024-04-07 17:44:04
举报
文章被收录于专栏:Asp.Net Web开发

1. 简介(快速理解)

在 ASP.NET 中,依赖注入 (Dependency Injection, DI) 提供了三种常见的服务生命周期模式:Singleton、Transient 和 Scoped。这些模式决定了服务的实例何时被创建、何时被销毁以及它们在应用程序中的生命周期。

1.1 Singleton(单例):

  • 生命周期: 在整个应用程序生命周期中只创建一个实例。
  • 使用场景: 当服务的状态不会因为多次请求而改变,且需要在整个应用程序中共享时使用。
  • 举例: 全局配置服务、日志服务等。
代码语言:csharp
复制
   services.AddSingleton<IMyService, MyService>();

1.2 Transient(瞬时):

  • 生命周期: 每次请求都会创建一个新的实例。
  • 使用场景: 当服务不保留状态,并且需要在每次请求时提供一个新的实例时使用。
  • 举例: Repository、临时计算服务等。
代码语言:csharp
复制
   services.AddTransient<IMyService, MyService>();

1.3 Scoped(作用域):

  • 生命周期: 在每个请求的作用域内创建一个实例,同一个请求中共享同一个实例。 services.AddScoped<IMyService, MyService>();使用这些生命周期模式时,要根据具体场景和需求做出选择。例如,对于全局配置服务,使用 Singleton 是合适的;对于每次请求都需要一个新实例的服务,使用 Transient 更为适当;而对于需要在请求期间保留状态的服务,使用 Scoped 是一个常见选择。
  • 使用场景: 当服务需要在整个请求期间保留状态,但在不同请求之间不需要共享状态时使用。
  • 举例: 数据库上下文服务、用户身份验证服务等。

在配置服务时,你可以根据需要选择适当的生命周期模式,确保服务的创建和销毁方式符合应用程序的需求。

2. 进一步理解Transient和Scope作用域(难点理解)

Singleton作用域是最容易理解的:进程全局唯一实例。对于Transient和Scope作用域就没有Singleton作用域那么容易理解了。下面通过例子详细说明他们的区别。

对于需要在请求期间保留状态的服务,使用 Scoped 是一个常见选择。如何理解这句话?

我们将创建一个服务,该服务在每个请求期间保留一个状态,并通过 TransientScoped 生命周期模式来比较它们的行为。

假设有一个简单的计数服务 CounterService

代码语言:csharp
复制
public class CounterService
{
    private int count = 0;

    public int Increment()
    {
        return ++count;
    }
}

现在,我们将在 ASP.NET Core 中注册这个服务,并测试 TransientScoped 生命周期模式的行为。

2.1 Transient 生命周期示例:

Startup.cs

代码语言:csharp
复制
// Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<CounterService>();

    // 其他配置...
}

HomeController.cs

代码语言:csharp
复制
// HomeController.cs

public class HomeController : Controller
{
    private readonly CounterService transientCounter;

    public HomeController(CounterService transientCounter)
    {
        this.transientCounter = transientCounter;
    }

    public IActionResult Index()
    {
        ViewBag.TransientCount1 = transientCounter.Increment();
        ViewBag.TransientCount2 = transientCounter.Increment();

        return View();
    }
}

在上述代码中,CounterService 被注册为 Transient 生命周期。每次对 CounterService 的请求都会创建一个新的实例。当我们在同一个请求中调用两次 Increment 方法时,count 变量会每次重新初始化。

2.2 Scoped 生命周期示例:

Startup.cs

代码语言:csharp
复制
// Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<CounterService>();

    // 其他配置...
}

HomeController.cs

代码语言:csharp
复制
// HomeController.cs

public class HomeController : Controller
{
    private readonly CounterService scopedCounter1;
    private readonly CounterService scopedCounter2;

    public HomeController(CounterService scopedCounter1, CounterService scopedCounter2)
    {
        this.scopedCounter1 = scopedCounter1;
        this.scopedCounter2 = scopedCounter2;
    }

    public IActionResult Index()
    {
        ViewBag.ScopedCount1 = scopedCounter1.Increment();
        ViewBag.ScopedCount2 = scopedCounter2.Increment();

        return View();
    }
}

在上述代码中,CounterService 被注册为 Scoped 生命周期。在同一个请求中,CounterService 的实例是共享的。当我们在同一个请求中调用两次 Increment 方法时,count 变量在整个请求期间保留其状态。

总的来说,Transient 生命周期每次都创建一个新的实例,适合不需要保留状态的服务。而 Scoped 生命周期在同一个请求期间共享一个实例,适合需要在请求期间保留状态的服务。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 简介(快速理解)
    • 1.1 Singleton(单例):
      • 1.2 Transient(瞬时):
        • 1.3 Scoped(作用域):
        • 2. 进一步理解Transient和Scope作用域(难点理解)
          • 2.1 Transient 生命周期示例:
            • 2.2 Scoped 生命周期示例:
            相关产品与服务
            日志服务
            日志服务(Cloud Log Service,CLS)是腾讯云提供的一站式日志服务平台,提供了从日志采集、日志存储到日志检索,图表分析、监控告警、日志投递等多项服务,协助用户通过日志来解决业务运维、服务监控、日志审计等场景问题。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档