18_三种服务的生命周期:Singleton、Scoped 和 Transient
三种服务的生命周期:Singleton、Scoped 和 Transient
Singleton
- Singleton(单例):这种服务只会被创建一次,并且在整个应用程序中重复使用。
- 这意味着所有使用这种服务的类都会得到同一个服务实例。这种服务适合用于创建成本高昂或需要全局共享的服务,
- 例如数据库连接或配置信息。您可以使用 AddSingleton 方法注册 Singleton 服务,例如:
services.AddSingleton<IProductService, ProductService>();
这行代码告诉容器,当有类需要 IProductService 时,就提供一个 ProductService 的实例,并且只创建一次,一直保持在内存中。¹
Scoped
- Scoped(范围内):这种服务每次请求(Request)都会被创建一次,并且在同一个请求中重复使用。这意味着在处理一个请求时,所有使用这种服务的类都会得到同一个服务实例,
- 但是不同的请求会得到不同的服务实例。这种服务适合用于创建和请求相关的服务,
- 例如 Entity Framework 的上下文(Context),它可以跟踪和保存请求的数据变化。您可以使用 AddScoped 方法注册 Scoped 服务,例如:
services.AddScoped<IProductService, ProductService>();
这行代码告诉容器,当有类需要 IProductService 时,就提供一个 ProductService 的实例,并且每个请求都创建一个新的实例,请求结束后销毁。¹
Transient
- Transient(临时):这种服务每次请求(Request)都会被创建,但是不会在请求中重复使用。
- 这意味着每次使用这种服务的类都会得到一个新的服务实例,即使是在同一个请求中。
- 这种服务适合用于创建轻量级、无状态的服务,例如日志记录或验证的服务。
您可以使用 AddTransient 方法注册 Transient 服务,例如:
services.AddTransient<IProductService, ProductService>();
这行代码告诉容器,当有类需要 IProductService 时,就提供一个 ProductService 的实例,并且每次都创建一个新的实例,使用完后销毁。¹
比喻
为了帮助您更好地理解这三种服务的生命周期,我可以用一个比喻来说明。假设您去一家餐厅吃饭,餐厅的服务就相当于 ASP.NET Core 的服务,而您的订单就相当于一个请求。那么:
-
Singleton 服务就像是餐厅的老板,他只有一个,而且在餐厅开业期间一直在场。无论您点什么菜,他都会亲自为您服务,并且记住您的喜好。他对所有的客人都是如此,所以他很忙,也很累,但是他很有经验,也很负责。
-
Scoped 服务就像是餐厅的服务员,他们每个人都负责一桌客人。当您进入餐厅时,会有一个服务员为您服务,他会为您点菜、上菜、结账,直到您离开餐厅。如果您再次来到餐厅,可能会遇到同一个服务员,也可能会遇到不同的服务员,但是他们都会为您提供专业的服务。他们对每桌客人都是如此,所以他们也很忙,但是他们很专注,也很友好。
-
Transient 服务就像是餐厅的厨师,他们每次都会为您做新鲜的菜。当您点了一个菜时,会有一个厨师为您做这个菜,并且只做这个菜,做完后就不再管您了。如果您再次点了同一个菜,可能会有同一个厨师为您做,也可能会有不同的厨师为您做,但是他们都会为您做出美味的菜。他们对每个菜都是如此,所以他们很快,也很灵活,但是他们不太关心您的其他需求。
实际例子
Singleton服务 -- 配置信息(Configuration)
- Singleton 服务:一个常见的使用 Singleton 服务的场景是配置信息(Configuration)。配置信息通常是在应用程序启动时从文件或数据库中读取的,它们在整个应用程序中是不变的,所以没有必要每次都重新读取。您可以使用 AddSingleton 方法将 IConfiguration 接口注册为 Singleton 服务,然后在任何需要配置信息的地方注入它,例如:
services.AddSingleton<IConfiguration>(Configuration);
这样,您就可以在控制器或其他服务中使用 IConfiguration 的实例来访问配置信息,例如:
public class HomeController : Controller { private readonly IConfiguration _configuration; public HomeController(IConfiguration configuration) { _configuration = configuration; } public IActionResult Index() { var title = _configuration["AppSettings:Title"]; ViewBag.Title = title; return View(); } }
Scoped 服务 -- Entity Framework Core 的上下文(DbContext)
- Scoped 服务:一个常见的使用 Scoped 服务的场景是 Entity Framework Core 的上下文(DbContext)。DbContext 是用于操作数据库的类,它可以跟踪和保存每个请求的数据变化。您可以使用 AddDbContext 方法将 DbContext 注册为 Scoped 服务,然后在需要操作数据库的地方注入它,例如:
services.AddDbContext<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
这样,您就可以在控制器或其他服务中使用 AppDbContext 的实例来操作数据库,例如:
public class ProductController : Controller { private readonly AppDbContext _context; public ProductController(AppDbContext context) { _context = context; } public IActionResult Index() { var products = _context.Products.ToList(); return View(products); } }
- Transient 服务 -- 日志记录(Logging)
- Transient 服务:一个常见的使用 Transient 服务的场景是日志记录(Logging)。日志记录是用于记录应用程序的运行情况的服务,它通常是轻量级的,不需要保持状态。您可以使用 AddLogging 方法将 ILoggerFactory 接口注册为 Transient 服务,然后在需要记录日志的地方注入它,例如:
services.AddLogging();
这样,您就可以在控制器或其他服务中使用 ILoggerFactory 的实例来创建日志记录器,例如:
public class HomeController : Controller { private readonly ILogger _logger; public HomeController(ILoggerFactory loggerFactory) { _logger = loggerFactory.CreateLogger<HomeController>(); } public IActionResult Index() { _logger.LogInformation("Index action executed"); return View(); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!