TL; DR
Geçici nesneler her zaman farklıdır; her denetleyiciye ve her hizmete yeni bir örnek sağlanır.
Kapsamlı nesneler bir istek içinde aynıdır, ancak farklı isteklerde farklıdır.
Singleton nesneleri her nesne ve her istek için aynıdır.
Daha fazla açıklama için ASP.NET belgelerindeki bu örnek farkı gösterir:
Bu kullanım ömrü ve kayıt seçenekleri arasındaki farkı göstermek için, bir veya daha fazla görevi benzersiz bir tanımlayıcıyla işlem olarak temsil eden basit bir arabirimi düşünün OperationId
. Bu hizmetin ömrünü nasıl yapılandırdığımıza bağlı olarak, kapsayıcı, istekte bulunan sınıfa hizmetin aynı veya farklı örneklerini sağlayacaktır. Hangi kullanım ömrünün talep edildiğini netleştirmek için, yaşam boyu seçenek başına bir tür oluşturacağız:
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
{
}
}
Bu arayüzleri Operation
, yapıcısında bir GUID kabul eden veya hiçbiri yoksa yeni bir GUID kullanan tek bir sınıf kullanarak uygularız :
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;
}
}
Daha sonra, içinde ConfigureServices
her tür, adlandırılan ömrüne göre kaba eklenir:
services.AddTransient<IOperationTransient, Operation>();
services.AddScoped<IOperationScoped, Operation>();
services.AddSingleton<IOperationSingleton, Operation>();
services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty));
services.AddTransient<OperationService, OperationService>();
IOperationSingletonInstance
Hizmetin bilinen bir kimliği olan belirli bir örneği kullandığını unutmayın Guid.Empty
, bu nedenle bu tür kullanıldığında açık olacaktır. Ayrıca OperationService
, diğer hizmetlerin her birine bağlı olan bir kaydı da kaydettik Operation
, böylece bu hizmetin her işlem türü için denetleyici ile aynı örneği mi yoksa yeni bir tane mi alıp almadığını net olarak göreceksiniz. Bu hizmetin yaptığı tek şey bağımlılıklarını özellikler olarak göstermektir, böylece görünümde görüntülenebilirler.
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;
}
}
}
Uygulamaya yapılan ayrı ayrı istekler içinde ve arasındaki nesne yaşamlarını göstermek için, örnek OperationsController
her tür IOperation
türün yanı sıra bir OperationService
. Index
Eylem daha sonra kontrolörün ve hizmetin tüm görüntüler OperationId
değerler.
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();
}
}
}
Şimdi bu denetleyici eylemine iki ayrı istek yapılıyor:
OperationId
Bir istek içinde ve istekler arasında hangi değerlerin değiştiğini gözlemleyin .
Geçici nesneler her zaman farklıdır; her denetleyiciye ve her hizmete yeni bir örnek sağlanır.
Kapsamlı nesneler bir istek içinde aynıdır, ancak farklı isteklerde farklıdır
Singleton nesneleri her nesne ve her istek için aynıdır (bir örnek sağlanmış olsun veya olmasın ConfigureServices
)