Asp.Net Core 1中的services.AddTransient,service.AddScope和service.AddSingleton方法有什么区别?

我想在Asp.Net Core 1中实现dependency injection 。 所以在将这些代码添加到ConfigureServices方法后,两种方式都可以工作。

services.AddTransientservice.AddScope方法有什么区别是Asp.Net Core 1?

public void ConfigureServices(IServiceCollection services) { // Add framework services. // Add application services. services.AddTransient<IEmailSender, AuthMessageSender>(); services.AddScope<IEmailSender, AuthMessageSender>(); } 

为了得到更多的解释,这个来自asp.net文档的例子显示了不同之处:

为了演示这些生存期和注册选项之间的差异,请考虑一个简单的界面,将一个或多个任务表示为具有唯一标识符OperationId的操作。 根据我们如何configuration此服务的生存期,容器将向请求的类提供相同或不同的服务实例。 为了明确要求哪个生命周期,我们将创build一个生命周期types选项:

 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。

接下来,在ConfigureServices中,根据其命名的生命周期将每个types添加到容器中:

 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的特定实例,因此在使用此types时将会清除。 我们还注册了一个依赖于其他操作types的OperationService,以便在请求中清楚这个服务是否获得与每个操作types相同的实例或者新的操作types。 所有这些服务都将它的依赖作为属性公开,以便它们可以显示在视图中。

 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,它请求每种IOperationtypes以及一个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对象都是相同的(不pipeConfigureServices中是否提供了一个实例)

在dotnet的dependency injection中有三个主要的生命周期:

在整个应用程序中创build单个实例的单例。 它首次创build实例,并在所有调用中重用相同的对象。

范围内的生命周期服务在范围内为每个请求创build一次。 它相当于当前范围内的Singleton。 例如。 在MVC中,它为每个http请求创build1个实例,但在同一个web请求中的其他调用中使用相同的实例。

每次请求时都会创build瞬态生命周期服务。 这个生命周期最适合轻量级,无状态的服务。

在这里你可以find和例子看到不同之处:

http://dotnetliberty.com/index.php/2015/10/15/asp-net-5-mvc6-dependency-injection-in-6-steps/

https://codewala.net/2015/04/30/your-dependency-injection-ready-asp-net-asp-net-5/

这是官方文档的链接:

https://docs.asp.net/en/latest/fundamentals/dependency-injection.html#service-lifetimes-and-registration-options

当MVC核心DI中有多个相同types的对象被注入时,Transient,scoped和singleton定义了对象创build过程。 如果你是新的dependency injection,你可以看到这个DI IOCvideo

你可以看到下面的控制器代码,我已经在构造函数中请求了两个“IDal”实例。 Transient,Scoped和Singleton定义是否在“_dal”和“_dal1”或不同的地方注入相同的实例。

 public class CustomerController : Controller { IDal dal = null; public CustomerController(IDal _dal ,IDal _dal1) { dal = _dal; // DI of MVC core // inversion of control } } 

瞬态:在瞬间,新的对象实例将被注入一个请求和响应。 以下是我显示GUID值的快照图像。

在这里输入图像说明

作用域: – 在作用域中,同一个对象实例将被注入一个请求和响应。

在这里输入图像说明

Singleton:在Singleton中,同一个对象将被注入到所有的请求和响应中。 在这种情况下,将创build一个对象的全局实例。

下面是一个简单的图解,从视觉上解释了上述的基础。

MVC DI图像

上面的图片是由SBSS团队在孟买培训期间参加ASP.NET MVC培训时得出的,非常感谢SBSS团队创build上述图片。

  • Singleton是应用程序域生命周期中的单个实例。
  • Scoped是作用域请求期间的单个实例,这意味着每个HTTP请求在ASP.NET中。
  • 每个代码请求的瞬态是一个实例。

通常情况下,代码请求应该通过一个构造函数参数来完成

 public MyConsumingClass(IDependency dependency) 

我想在@ akazemis的回答中指出,DI中的“服务”并不意味着RESTful服务; 服务是提供function的依赖关系的实现。