TL; DR
Các đối tượng thoáng qua luôn khác nhau; một phiên bản mới được cung cấp cho mọi bộ điều khiển và mọi dịch vụ.
Các đối tượng có phạm vi giống nhau trong một yêu cầu, nhưng khác nhau giữa các yêu cầu khác nhau.
Các đối tượng Singleton giống nhau cho mọi đối tượng và mọi yêu cầu.
Để làm rõ hơn, ví dụ này từ tài liệu ASP.NET cho thấy sự khác biệt:
Để chứng minh sự khác biệt giữa các tùy chọn đăng ký trọn đời và đăng ký này, hãy xem xét một giao diện đơn giản đại diện cho một hoặc nhiều tác vụ dưới dạng một thao tác với một mã định danh duy nhất , OperationId
. Tùy thuộc vào cách chúng tôi định cấu hình trọn đời cho dịch vụ này, container sẽ cung cấp các phiên bản dịch vụ giống hoặc khác nhau cho lớp yêu cầu. Để làm rõ thời gian tồn tại đang được yêu cầu, chúng tôi sẽ tạo một loại cho mỗi tùy chọn trọn đời:
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
{
}
}
Chúng tôi triển khai các giao diện này bằng một lớp duy nhất, Operation
chấp nhận GUID trong hàm tạo của nó hoặc sử dụng GUID mới nếu không được cung cấp:
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;
}
}
Tiếp theo, trong ConfigureServices
mỗi loại được thêm vào thùng chứa theo tuổi thọ được đặt tên của nó:
services.AddTransient<IOperationTransient, Operation>();
services.AddScoped<IOperationScoped, Operation>();
services.AddSingleton<IOperationSingleton, Operation>();
services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty));
services.AddTransient<OperationService, OperationService>();
Lưu ý rằng IOperationSingletonInstance
dịch vụ đang sử dụng một phiên bản cụ thể với ID đã biết Guid.Empty
, vì vậy sẽ rõ ràng khi loại này được sử dụng. Chúng tôi cũng đã đăng ký một OperationService
tùy thuộc vào từng Operation
loại khác, do đó sẽ rõ ràng trong yêu cầu liệu dịch vụ này có nhận được cùng một thể hiện như bộ điều khiển hay loại mới cho từng loại hoạt động hay không. Tất cả các dịch vụ này làm là phơi bày các phụ thuộc của nó dưới dạng các thuộc tính, vì vậy chúng có thể được hiển thị trong dạng xem.
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;
}
}
}
Để thể hiện thời gian sống của đối tượng trong và giữa các yêu cầu riêng biệt cho ứng dụng, mẫu bao gồm một OperationsController
yêu cầu từng loại IOperation
cũng như một loại OperationService
. Các Index
hành động sau đó hiển thị tất cả các bộ điều khiển và dịch vụ OperationId
giá trị.
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();
}
}
}
Bây giờ hai yêu cầu riêng biệt được thực hiện cho hành động điều khiển này:
Quan sát OperationId
giá trị nào thay đổi trong một yêu cầu và giữa các yêu cầu.
Các đối tượng thoáng qua luôn khác nhau; một phiên bản mới được cung cấp cho mọi bộ điều khiển và mọi dịch vụ.
Các đối tượng có phạm vi giống nhau trong một yêu cầu, nhưng khác nhau giữa các yêu cầu khác nhau
Các đối tượng Singleton giống nhau cho mọi đối tượng và mọi yêu cầu (bất kể trường hợp có được cung cấp hay không ConfigureServices
)