在ConfigureServices方法中的容器注册每一个应用程序的服务,Asp.Core均可觉得每一个应用程序提供三种服务生命周期:
●Transient(暂时):每次请求都会建立一个新的实例。这种生命周期最适合轻量级,无状态服务。
●Scoped(做用域):在同一个做用域内只初始化一个实例 ,能够理解为每个请求只建立一个实例,同一个请求会在一个做用域内。
●Singleton(单例):整个应用程序生命周期之内只建立一个实例,后续每一个请求都使用相同的实例。若是应用程序须要单例行为,建议让服务容器管理服务的生命周期,而不是在本身的类中实现单例模式。ui
为了演示生命周期和注册选项之间的差别,请考虑如下接口,将任务表示为具备惟一标识符 OperationId 的操做。根据如下接口配置操做服务的生命周期的方式,容器在类请求时提供相同或不一样的服务实例:this
public interface IOperation { Guid OperationId { get; } } public interface IOperationTransient : IOperation { } public interface IOperationScoped : IOperation { } public interface IOperationSingleton : IOperation { } public interface IOperationSingletonInstance : IOperation { }
上面四种服务接口在 Operation 类中实现。调用Operation类时将自动生成一个GUID,下面是Operation类的实现:spa
public class Operation : IOperationTransient, IOperationScoped, IOperationSingleton, IOperationSingletonInstance { public Operation() : this(Guid.NewGuid()) { } public Operation(Guid id) { OperationId = id; } public Guid OperationId { get; private set; } }
再注册一个OperationService服务实例,当经过依赖关系注入请求 OperationService 实例时,它将接收每一个服务的新实例或基于从属服务(Operation)的生命周期的现有实例。OperationService 服务做用就是第二次调用 Operation类,查看Operation类实例的做用域变化。3d
public class OperationService { public OperationService( IOperationTransient transientOperation, IOperationScoped scopedOperation, IOperationSingleton singletonOperation, IOperationSingletonInstance instanceOperation) { _transientOperation = transientOperation; _scopedOperation = scopedOperation; _singletonOperation = singletonOperation; _singletonInstanceOperation = instanceOperation; } public IOperationTransient _transientOperation { get; } public IOperationScoped _scopedOperation { get; } public IOperationSingleton _singletonOperation { get; } public IOperationSingletonInstance _singletonInstanceOperation { get; } }
而后在Startup.ConfigureServices()服务容器中注册各个生命周期的实例:code
public void ConfigureServices(IServiceCollection services) { services.AddTransient<IOperationTransient, Operation>(); services.AddScoped<IOperationScoped, Operation>(); services.AddSingleton<IOperationSingleton, Operation>(); services.AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty)); // OperationService depends on each of the other Operation types. services.AddTransient<OperationService, OperationService>(); }
再在IndexModel模块里面调用OnGet方法输出,观察IOperation与OperationService类属性OperationId 值的变化:对象
public class IndexModel : PageModel { public OperationService _operationService { get; } public IOperationTransient _transientOperation { get; } public IOperationScoped _scopedOperation { get; } public IOperationSingleton _singletonOperation { get; } public IOperationSingletonInstance _singletonInstanceOperation { get; } public IndexModel( OperationService operationService, IOperationTransient transientOperation, IOperationScoped scopedOperation, IOperationSingleton singletonOperation, IOperationSingletonInstance singletonInstanceOperation) { _operationService = operationService; _transientOperation = transientOperation; _scopedOperation = scopedOperation; _singletonOperation = singletonOperation; _singletonInstanceOperation = singletonInstanceOperation; } public void OnGet() { Console.WriteLine("IOperation操做:"); Console.WriteLine("暂时:" + _transientOperation.OperationId.ToString()); Console.WriteLine("做用域:" + _scopedOperation.OperationId.ToString()); Console.WriteLine("单例:" + _singletonOperation.OperationId.ToString()); Console.WriteLine("实例:" + _singletonInstanceOperation.OperationId.ToString()); Console.WriteLine("OperationService操做:"); Console.WriteLine("暂时:" + _operationService._transientOperation.OperationId.ToString()); Console.WriteLine("做用域:" + _operationService._scopedOperation.OperationId.ToString()); Console.WriteLine("单例:" + _operationService._singletonOperation.OperationId.ToString()); Console.WriteLine("实例:" + _operationService._singletonInstanceOperation.OperationId.ToString()); } }
执行IndexModel 类输出结果:blog
由图总结以下:
2.1 Transient(暂时):每次调用服务的时候都会建立一个新的实例。即在IndexModel类的局部方法或属性中(这里是OnGet方法)实例化一个依赖对象Operation类,伪代码是:接口
public class IndexModel: PageModel { public void OnGet() { //调用IndexModel类时,实例化了两次Operation类 //第一次 OperationService operationService=new OperationService(); //第二次 IOperationTransient TransientOperation=new Operation(); } }
2.2 Scoped(做用域):一次请求(Action)内对象实例是相同的,但每次请求会产生一个新实例。至关于在IndexModel类的全局中实例化一次依赖对象Operation类,伪代码是:生命周期
OperationService operationService = null; public IndexModel() { operationService = new OperationService(); operationService._scopedOperation = new Operation(); } public void OnGet() { operationService._scopedOperation.OperationId; IOperationScoped operationScoped = operationService._scopedOperation; operationScoped.OperationId }
2.3 Singleton(单例):首次请求初始化同一个实例,后续每次请求都使用同一个实例。至关于在整个应用Application中只实例化一次实例,常见的单例模式。作用域
参考文献:
在ASP.NET Core依赖注入