练习 - 探索服务生存期

已完成

在上一练习中,你使用单一实例服务生存期注册了服务。 在代码评审中,团队主管要求调查单一实例、作用域和暂时性服务生存期之间的差异

测试单一实例服务生存期

  1. 如果之前的练习中已经运行了应用,那么它应当仍在运行。 如果没有如期运行,请按照之前的方式运行应用。

  2. 刷新浏览器窗口并留意欢迎消息中显示的时间。

  3. 等待几秒钟,然后再次刷新浏览器窗口。 欢迎消息没有变化。 时间戳和 GUID 保持不变。

    欢迎消息中显示的时间和 GUID 没有变化,因为 WelcomeService 服务注册为单一实例服务。 在应用启动时创建一次服务,并在应用的生存期内重复使用。 每个客户端的每个请求都使用相同的服务实例。 不会创建其他服务实例。

  4. 通过在 Visual Studio Code 中按 Shift+F5 来停止应用。

测试作用域服务生存期

要了解作用域服务生存期,需要更改注册 WelcomeService 服务的方式。

  1. 在 Program.cs 文件中,更改 WelcomeService 服务的注册以使用作用域服务生存期:

    builder.Services.AddScoped<IWelcomeService, WelcomeService>();
    

    此代码将 WelcomeService 类注册到具有作用域生存期的服务容器。

  2. 请按照之前的方式运行应用。

  3. 请留意欢迎消息中显示的时间和 GUID。 刷新浏览器窗口并注意每次时间都会变化,GUID 也是不同的。

    欢迎消息中显示的数据会变化,因为 WelcomeService 服务现已注册为作用域服务。 每个客户端请求都会单独创建一次服务,请求完成后,该服务就会被释放。 每个客户端的每个请求都使用新的服务实例。

  4. 通过在 Visual Studio Code 中按 Shift+F5 来停止应用。

  5. 让我们来探讨一下,在同一个请求中尝试使用同一 WelcomeService 服务的两个实例时,作用域服务生存期的行为。 将 app.MapGet() 行更改为以下代码:

    app.MapGet("/", async (IWelcomeService welcomeService1, IWelcomeService welcomeService2) => 
        {
            string message1 = $"Message1: {welcomeService1.GetWelcomeMessage()}";
            string message2 = $"Message2: {welcomeService2.GetWelcomeMessage()}";
            return $"{message1}\n{message2}";
        });
    

    在上述代码中:

    • app.MapGet() 委托现在有两个类型均为 IWelcomeService 的参数。 委托会生成两条欢迎消息,每个服务实例各一条。
    • 委托在单个响应中返回这两条消息。
  6. 请按照之前的方式运行应用。 请注意,即使两条欢迎消息是在不同时间生成的,并且它们是作为单独的参数传递给委托的,但消息内容是相同的。

    此行为是因为 WelcomeService 服务注册为作用域服务。 该服务是针对每个客户端请求单独创建的,在同一个请求中,所有需要它的组件都会获得同一个实例。 welcomeService1welcomeService2 都引用 WelcomeService 服务的同一实例。

  7. 多次刷新页面。 请注意,欢迎消息中的时间戳和 GUID 每次都会变化,但两条消息始终相同。

  8. 通过在 Visual Studio Code 中按 Shift+F5 来停止应用。

测试暂时性服务生存期

现在,让我们检查暂时性服务生存期。

  1. 更改 WelcomeService 服务的注册以使用暂时性服务生存期:

    builder.Services.AddTransient<IWelcomeService, WelcomeService>();
    

    此代码将 WelcomeService 类注册到具有暂时性生存期的服务容器。

  2. 请按照之前的方式运行应用。 这两条消息中的时间保持不变,因为 WelcomeService 服务的两个实例是同时创建的。 但是,每个消息中的 GUID 不同,因为每个服务实例都是唯一的。

    此行为代表暂时性服务生存期。 每次将服务注入组件时,都会创建新的服务实例。 由于它注入到委托中两次,因此会创建两个服务实例。

  3. 多次刷新页面。 每次刷新页面时,两个消息中的时间戳始终相同,但每个消息中的 GUID 不同。

  4. 通过在 Visual Studio Code 中按 Shift+F5 来停止应用。