AddTransient、AddScoped 和 AddSingleton 服务差异

编程入门 行业动态 更新时间:2024-10-17 15:31:21
本文介绍了AddTransient、AddScoped 和 AddSingleton 服务差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我想在 ASP.NET Core 中实现

观察哪些 OperationId 值在请求内和请求之间变化.

  • 瞬态对象总是不同的;为每个控制器和每个服务提供一个新实例.

  • 作用域对象在一个请求中是相同的,但在不同的请求中是不同的

  • 单个对象对于每个对象和每个请求都是相同的(无论ConfigureServices 中是否提供了实例)

I want to implement dependency injection (DI) in ASP.NET Core. So after adding this code to ConfigureServices method, both ways work.

What is the difference between the services.AddTransient and service.AddScoped methods in ASP.NET Core?

public void ConfigureServices(IServiceCollection services) { // Add framework services. // Add application services. services.AddTransient<IEmailSender, AuthMessageSender>(); services.AddScoped<IEmailSender, AuthMessageSender>(); }

解决方案

TL;DR

Transient objects are always different; a new instance is provided to every controller and every service.

Scoped objects are the same within a request, but different across different requests.

Singleton objects are the same for every object and every request.

For more clarification, this example from .NET documentation shows the difference:

To demonstrate the difference between these lifetime and registration options, consider a simple interface that represents one or more tasks as an operation with a unique identifier, OperationId. Depending on how we configure the lifetime for this service, the container will provide either the same or different instances of the service to the requesting class. To make it clear which lifetime is being requested, we will create one type per lifetime option:

using System; namespace DependencyInjectionSample.Interfaces { public interface IOperation { Guid OperationId { get; } } public interface IOperationTransient : IOperation { } public interface IOperationScoped : IOperation { } public interface IOperationSingleton : IOperation { } public interface IOperationSingletonInstance : IOperation { } }

We implement these interfaces using a single class, Operation, that accepts a GUID in its constructor, or uses a new GUID if none is provided:

using System; using DependencyInjectionSample.Interfaces; namespace DependencyInjectionSample.Classes { public class Operation : IOperationTransient, IOperationScoped, IOperationSingleton, IOperationSingletonInstance { Guid _guid; public Operation() : this(Guid.NewGuid()) { } public Operation(Guid guid) { _guid = guid; } public Guid OperationId => _guid; } }

Next, in ConfigureServices, each type is added to the container according to its named lifetime:

services.AddTransient<IOperationTransient, Operation>(); services.AddScoped<IOperationScoped, Operation>(); services.AddSingleton<IOperationSingleton, Operation>(); services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty)); services.AddTransient<OperationService, OperationService>();

Note that the IOperationSingletonInstance service is using a specific instance with a known ID of Guid.Empty, so it will be clear when this type is in use. We have also registered an OperationService that depends on each of the other Operation types, so that it will be clear within a request whether this service is getting the same instance as the controller, or a new one, for each operation type. All this service does is expose its dependencies as properties, so they can be displayed in the view.

using DependencyInjectionSample.Interfaces; namespace DependencyInjectionSample.Services { public class OperationService { public IOperationTransient TransientOperation { get; } public IOperationScoped ScopedOperation { get; } public IOperationSingleton SingletonOperation { get; } public IOperationSingletonInstance SingletonInstanceOperation { get; } public OperationService(IOperationTransient transientOperation, IOperationScoped scopedOperation, IOperationSingleton singletonOperation, IOperationSingletonInstance instanceOperation) { TransientOperation = transientOperation; ScopedOperation = scopedOperation; SingletonOperation = singletonOperation; SingletonInstanceOperation = instanceOperation; } } }

To demonstrate the object lifetimes within and between separate individual requests to the application, the sample includes an OperationsController that requests each kind of IOperation type as well as an OperationService. The Index action then displays all of the controller’s and service’s OperationId values.

using DependencyInjectionSample.Interfaces; using DependencyInjectionSample.Services; using Microsoft.AspNetCore.Mvc; namespace DependencyInjectionSample.Controllers { public class OperationsController : Controller { private readonly OperationService _operationService; private readonly IOperationTransient _transientOperation; private readonly IOperationScoped _scopedOperation; private readonly IOperationSingleton _singletonOperation; private readonly IOperationSingletonInstance _singletonInstanceOperation; public OperationsController(OperationService operationService, IOperationTransient transientOperation, IOperationScoped scopedOperation, IOperationSingleton singletonOperation, IOperationSingletonInstance singletonInstanceOperation) { _operationService = operationService; _transientOperation = transientOperation; _scopedOperation = scopedOperation; _singletonOperation = singletonOperation; _singletonInstanceOperation = singletonInstanceOperation; } public IActionResult Index() { // ViewBag contains controller-requested services ViewBag.Transient = _transientOperation; ViewBag.Scoped = _scopedOperation; ViewBag.Singleton = _singletonOperation; ViewBag.SingletonInstance = _singletonInstanceOperation; // Operation service has its own requested services ViewBag.Service = _operationService; return View(); } } }

Now two separate requests are made to this controller action:

Observe which of the OperationId values varies within a request, and between requests.

  • Transient objects are always different; a new instance is provided to every controller and every service.

  • Scoped objects are the same within a request, but different across different requests

  • Singleton objects are the same for every object and every request (regardless of whether an instance is provided in ConfigureServices)

更多推荐

AddTransient、AddScoped 和 AddSingleton 服务差异

本文发布于:2023-11-13 14:55:19,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1584634.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:差异   AddTransient   AddScoped   AddSingleton

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!