TL;博士
瞬态对象总是不同的;将向提供一个新实例每个控制器和每个服务。作用域对象在请求中是相同的,但在请求中不同不同的请求。单个对象对于每个对象和每个请求都是相同的。
为了进一步澄清,.NET文档中的这个示例显示了不同之处:
要演示这些生存期和注册选项之间的区别,请考虑一个简单的接口,该接口将一个或多个任务表示为具有唯一标识符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,则使用新的GUID:
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,它依赖于其他每个操作类型,因此在请求中可以清楚地看到,该服务是获得与控制器相同的实例,还是为每个操作类型获得一个新的实例。此服务所做的只是将其依赖项公开为财产,以便可以在视图中显示它们。
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。索引操作然后显示所有控制器和服务的OperationId值。
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值的变化。
瞬态对象总是不同的;向每个控制器和每个服务提供新实例。作用域对象在请求中相同,但在不同的请求中不同单个对象对于每个对象和每个请求都是相同的(无论ConfigureServices中是否提供了实例)