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:
2. Program.cs:
- 这是应用程序的入口点。
- 它创建一个 Web 主机并配置它使用
Startup
类。
3. HomeController.cs:
- 该类定义了处理传入 HTTP 请求的
HomeController
。
- 构造函数注入所有六个服务实例:Transient、Scoped 和 Singleton 各两个。
Index
方法使用 GetOperationID
方法检索并显示每个注入服务的操作 ID。
4. OperationService.cs:
- 该类实现了所有三个服务接口:
ITransientService
、IScopedService
和 ISingletonService
。
- 它定义了一个单一构造函数,该构造函数在创建对象时生成唯一标识符 (
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(); |
| } |
| } |
| |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战