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:
- 该类实现了所有三个服务接口:
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();
}
}
标签:TransientScopedSingleton,singlton,System,transient,scoped,cs,using,public,GetOpe
From: https://www.cnblogs.com/zhuoss/p/18060014