我想在 ASP.NET Core中实现依赖注入(DI)。因此,将此代码添加到ConfigureServices方法后,两种方式都有效。
ConfigureServices
ASP.NET Core 中的services.AddTransient和方法有什么区别?service.AddScoped
services.AddTransient
service.AddScoped
public void ConfigureServices(IServiceCollection services) { // Add framework services. // Add application services. services.AddTransient<IEmailSender, AuthMessageSender>(); services.AddScoped<IEmailSender, AuthMessageSender>(); }
Transient objects总是不同的;为每个控制器和每个服务提供一个新实例。 作用域对象在一个请求中是相同的,但在不同的请求中是不同的。 对于每个对象和每个请求,单例对象都是相同的。
Transient objects总是不同的;为每个控制器和每个服务提供一个新实例。
作用域对象在一个请求中是相同的,但在不同的请求中是不同的。
对于每个对象和每个请求,单例对象都是相同的。
为了更清楚地说明,.NET 文档中的这个示例显示了差异:
为了演示这些生命周期和注册选项之间的区别,请考虑一个简单的接口,它将一个或多个任务表示为具有唯一标识符的操作,OperationId. 根据我们如何配置此服务的生命周期,容器将为请求类提供相同或不同的服务实例。为了明确请求哪个生命周期,我们将为每个生命周期创建一个类型选项:
OperationId
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 { } }
我们使用单个类来实现这些接口,该类Operation在其构造函数中接受 GUID,如果没有提供,则使用新的 GUID:
Operation
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; } }
接下来,在 中ConfigureServices,每种类型都根据其命名生命周期添加到容器中:
services.AddTransient<IOperationTransient, Operation>(); services.AddScoped<IOperationScoped, Operation>(); services.AddSingleton<IOperationSingleton, Operation>(); services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty)); services.AddTransient<OperationService, OperationService>();
请注意,该IOperationSingletonInstance服务正在使用具有已知 ID 的特定实例Guid.Empty,因此在使用此类型时会很清楚。我们还注册了OperationService依赖于其他每个Operation类型的一个,以便在请求中清楚该服务是获取与控制器相同的实例,还是为每个操作类型获取一个新实例。该服务所做的只是将其依赖项作为属性公开,因此它们可以显示在视图中。
IOperationSingletonInstance
Guid.Empty
OperationService
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; } } }
为了演示对应用程序的单独请求之内和之间的对象生命周期,该示例包括一个OperationsController请求每种类型IOperation的OperationService. 然后该Index操作显示所有控制器和服务的OperationId值。
OperationsController
IOperation
Index
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(); } } }
现在对该控制器操作发出两个单独的请求:
观察OperationId请求中和请求之间的哪些值不同。