日常生活的交流与学习

首页 新随笔 联系 管理

ASP.NET 中的 Transient、Scoped 和 Singleton区别

该代码展示了 ASP.NET Core 中服务生命周期管理的不同选项,特别关注 Transient、Scoped 和 Singleton 服务。

说明

Transient:

  • 每次请求都会创建一个新的 OperationService 实例,并生成一个新的 GUID。
  • 因此,同一个请求中的不同控制器或服务调用将获得不同的 ID。

Scoped:

  • 同一个 HTTP 请求中所有对 OperationService 的引用都会返回相同的实例。
  • 因此,同一个请求中的所有控制器或服务调用将获得相同的 ID。

Singleton:

  • 应用程序生命周期内所有对 OperationService 的引用都会返回相同的实例。
  • 因此,应用程序运行期间所有对 GetOperationID 的调用都会返回相同的 ID。

1. Startup.cs:

  • 该文件通过注册服务和定义中间件管道来配置应用程序。

  • ConfigureServices 方法中,注册了三个服务:

    • ITransientService: 使用 AddTransient 注册为瞬态。每次请求都会创建一个新实例。

    • IScopedService: 使用 AddScoped 注册为范围。同一 HTTP 请求中会共享一个实例,但每个新请求都会创建一个新实例。

    • ISingletonService: 使用 AddSingleton 注册为单例。应用程序生命周期内会共享一个实例。

    • 这三个服务都由 OperationService 类实现。

2. Program.cs:

  • 这是应用程序的入口点。
  • 它创建一个 Web 主机并配置它使用 Startup 类。

3. HomeController.cs:

  • 该类定义了处理传入 HTTP 请求的 HomeController
  • 构造函数注入所有六个服务实例:Transient、Scoped 和 Singleton 各两个。
  • Index 方法使用 GetOperationID 方法检索并显示每个注入服务的操作 ID。

4. OperationService.cs:

  • 该类实现了所有三个服务接口:ITransientServiceIScopedServiceISingletonService
  • 它定义了一个单一构造函数,该构造函数在创建对象时生成唯一标识符 (Guid)。
  • GetOperationID 方法只是返回生成的 ID。

5. 接口文件 (ITransientService.cs, IScopedService.cs, ISingletonService.cs):

  • 这些文件定义每个服务类型的接口,仅包含 GetOperationID 方法声明。

总体而言,此代码演示了:

  • 如何在 ASP.NET Core 中注册具有不同生命周期的服务。
  • 如何在控制器中注入和使用这些服务。
  • Transient、Scoped 和 Singleton 服务之间的行为差异。

代码示例

TransientScopedSingleton-master/Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace TransientScopedSingleton
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddTransient<ITransientService, OperationService>();
            services.AddScoped<IScopedService, OperationService>();
            services.AddSingleton<ISingletonService, OperationService>();
           
            services.AddControllersWithViews();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

TransientScopedSingleton-master/Program.cs

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace TransientScopedSingleton
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

TransientScopedSingleton-master/Controllers/HomeController.cs

using Microsoft.AspNetCore.Mvc;

namespace TransientScopedSingleton.Controllers
{
    public class HomeController : Controller
    {
        private readonly ITransientService _transientService1;
        private readonly ITransientService _transientService2;
        private readonly IScopedService _scopedService1;
        private readonly IScopedService _scopedService2;
        private readonly ISingletonService _singletonService1;
        private readonly ISingletonService _singletonService2;
        public HomeController(
            ITransientService transientService1,
            ITransientService transientService2,
            IScopedService scopedService1,
            IScopedService scopedService2,
            ISingletonService singletonService1,
            ISingletonService singletonService2)
        {
            _transientService1 = transientService1;
            _transientService2 = transientService2;

            _scopedService1 = scopedService1;
            _scopedService2 = scopedService2;

            _singletonService1 = singletonService1;
            _singletonService2 = singletonService2;

        }

        public IActionResult Index()
        {
            ViewBag.transient1 = _transientService1.GetOperationID().ToString();
            ViewBag.transient2 = _transientService2.GetOperationID().ToString();

            ViewBag.scoped1 = _scopedService1.GetOperationID().ToString();
            ViewBag.scoped2 = _scopedService2.GetOperationID().ToString();

            ViewBag.singleton1 = _singletonService1.GetOperationID().ToString();
            ViewBag.singleton2 = _singletonService2.GetOperationID().ToString();
            return View();
        }
    }
}

TransientScopedSingleton-master/Services/OperationService.cs

using System;

namespace TransientScopedSingleton
{
    public class OperationService : ITransientService, IScopedService, ISingletonService
    {
        Guid id;
        public OperationService()
        {
            id = Guid.NewGuid();
        }
        public Guid GetOperationID()
        {
            return id;
        }
    }
}

TransientScopedSingleton-master/Services/ITransientService.cs

using System;

namespace TransientScopedSingleton
{
    public interface ITransientService
    {
        Guid GetOperationID();
    }
}

TransientScopedSingleton-master/Services/IScopedService.cs

using System;

namespace TransientScopedSingleton
{
    public interface IScopedService
    {
        Guid GetOperationID();
    }
}

TransientScopedSingleton-master/Services/ISingletonService.cs

using System;

namespace TransientScopedSingleton
{
    public interface ISingletonService
    {
        Guid GetOperationID();
    }
}

posted on 2024-03-07 23:10  lazycookie  阅读(37)  评论(0编辑  收藏  举报