怪物奇妙物语

宇宙无敌超级美少男的怪物奇妙物语

首页 新随笔 联系 管理
  819 随笔 :: 0 文章 :: 2 评论 :: 16万 阅读

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   超级无敌美少男战士  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示