示例
ICitiesService.cs中添加ServiceInstanceId字段,用于每次构造示例都创建一个GUID类型的Id,通过一次性出入3次查看Transient, Scoped, Singleton的区别:
ICitiesService.cs
public interface ICitiesService
{
Guid ServiceInstanceId { get; }
List<string> GetCities();
}
CitiesService.cs
public class CitiesService : ICitiesService
{
private List<string> _cities;
private Guid _serviceInstanceId;
public Guid ServiceInstanceId
{
get
{
return _serviceInstanceId;
}
}
public CitiesService()
{
_serviceInstanceId = Guid.NewGuid();
_cities = new List<string>()
{
"Lodon",
"Paris",
"New York",
"Tokyo",
"Rome"
};
}
public List<string> GetCities()
{
return _cities;
}
}
HomeController
public class HomeController : Controller
{
//private readonly CitiesService _citiesService;
private readonly ICitiesService _citiesService1;
private readonly ICitiesService _citiesService2;
private readonly ICitiesService _citiesService3;
public HomeController(ICitiesService services1,
ICitiesService services2,
ICitiesService services3)
{
//_citiesService = new CitiesService();
_citiesService1 = services1;
_citiesService2 = services2;
_citiesService3 = services3;
}
[Route("/")]
public IActionResult Index()
{
List<string> cities = _citiesService1.GetCities();
ViewBag.Ins1 = _citiesService1.ServiceInstanceId;
ViewBag.Ins2 = _citiesService2.ServiceInstanceId;
ViewBag.Ins3 = _citiesService3.ServiceInstanceId;
return View(cities);
}
}
Index.cshtml
@model IEnumerable<string>
@{
ViewBag.Title = "Home";
}
<h1>Home</h1>
<ul class="list">
@foreach (string city in Model)
{
<li>@city</li>
}
</ul>
<div>Ins1: @ViewBag.Ins1</div>
<div>Ins2: @ViewBag.Ins2</div>
<div>Ins3: @ViewBag.Ins3</div>
Program.cs
using ServiceContracts;
using Services;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.Add(new ServiceDescriptor(
typeof(ICitiesService),
typeof(CitiesService),
ServiceLifetime.Transient));
//builder.Services.AddScoped<ICitiesService, CitiesService>();
var app = builder.Build();
//app.MapGet("/", () => "Hello World!");
app.UseStaticFiles();
app.UseRouting();
app.MapControllers();
app.Run();
ServiceLifetime.Transient单次请求得到的3个Id都不一样;
ServiceLifetime.Scoped单次请求得到的3个Id一样,但是刷新后得到的3个Id一样但是和上次请求不一样;
ServiceLifetime.Singletond单次请求得到的3个Id一样,且刷新后得到的3个Id一样且和上次请求一样,没有变化;
使用场景
缓存数据处理或者发送邮件,可以使用Transient;
EF Core使用Scoped;
整个程序在内存中共享数据,比如一个数据库的几张表,要在内存中处理完数据后,再插入到数据库中的情况使用Singleton;
Gitee获取源码: