我想在ASP.NET核心中实现dependency injection (DI)。因此,在将此代码添加到ConfigureServices
方法后,这两种方法都可以工作。
ASP.NET核心中的services.AddTransient
和service.AddScoped
方法有什么不同?
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
// Add application services.
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddScoped<IEmailSender, AuthMessageSender>();
}
发布于 2016-07-01 15:27:11
TL;DR
瞬态对象总是不同的;每个控制器和每个服务都会有一个新的实例。
作用域对象在一个请求中是相同的,但在不同的请求中是不同的。
单例对象对于每个对象和每个请求都是相同的。
为了得到更多的说明,.NET documentation中的这个例子展示了其中的区别:
根据我们如何配置此服务的生存期,容器将向请求类提供相同或不同的服务实例。为了明确请求哪个生存期,我们将为每个生存期选项创建一个类型:
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
{
}
}
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
的特定实例,因此可以清楚地知道何时使用了此类型。我们还注册了一个依赖于每个其他Operation
类型的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;
}
}
}
为了演示对应用程序的单独请求内和请求之间的对象生存期,该示例包括一个请求每种IOperation
类型的OperationsController
以及一个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
值在请求内和请求之间发生变化。
对于每个对象和每个请求,
ConfigureServices
)中是否提供了实例
发布于 2016-07-01 14:29:19
在.NET的依赖注入中,有三个主要的生命周期:
单例,在整个应用程序中创建单个实例。它第一次创建实例,并在所有调用中重用同一对象。
作用域内的每个请求都会创建一次作用域生存期服务。等同于当前作用域中的单例。例如,在MVC中,它为每个HTTP请求创建一个实例,但它在同一web请求内的其他调用中使用相同的实例。
每次请求临时生存期服务时都会创建这些服务。此生命周期最适合于轻量级的无状态服务。
在这里,您可以找到和示例来了解其中的区别:
(由于死链接而导致web存档链接)
这是官方文档的链接:
发布于 2020-05-11 17:15:56
使用哪一个?
瞬态
对于
作用域
当您想要维护请求中的状态时,
单例
随着时间的推移,这些服务中的
在需要维护应用程序范围状态的地方使用单例。应用程序配置或参数、日志记录服务、数据缓存是您可以使用单例的一些示例。
将具有不同生命周期的服务注入另一个服务
https://stackoverflow.com/questions/38138100
复制相似问题