TL; DR
Перехідні об'єкти завжди різні; новий екземпляр надається кожному контролеру та кожній службі.
Об'єкти, що охоплюють область, однакові в запиті, але різні в різних запитах.
Одиничні об'єкти однакові для кожного об'єкта та кожного запиту.
Для додаткового уточнення цей приклад із документації ASP.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, якщо такого не передбачено:
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
служба використовує певний екземпляр з відомим ідентифікатором Guid.Empty
, тому буде зрозуміло, коли цей тип використовується. Ми також зареєстрували дані, OperationService
які залежать від кожного з інших Operation
типів, так що в запиті буде зрозуміло, чи отримує цей сервіс той самий екземпляр, що і контролер, або новий для кожного типу операцій. Все, що ця послуга робить, полягає у викритті її залежностей як властивостей, тому вони можуть відображатися у поданні.
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
типу, а також an OperationService
. Потім Index
дія відображає всі значення контролера та служби 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
значення змінюється в межах запиту та між запитами.
Перехідні об'єкти завжди різні; новий екземпляр надається кожному контролеру та кожній службі.
Об'єкти, що охоплюють область, однакові в запиті, але різні в різних запитах
Об'єкти Singleton однакові для кожного об'єкта та кожного запиту (незалежно від того, чи надається примірник ConfigureServices
)