在asp.net core中的DI生命周期有一个Scoped是根据请求走的,也就是说在处理一次请求时,Scope生命周期所提供的服务是同一个实例。它是用IServiceScope是实现的。但是我们要知道何时构建的IServiceScope以及IServiceScope何时被销毁掉
先说结论IServiceScope是根据当前的RequestServicesFeature内作为_scope成员存在的,只要知道RequestServicesFeature何时创建,何时销毁就了解整http request DI的生命周期
在net core 默认的DI中你直接build 出来的servicepProvider 用它去获取的实例对象Scoped & Singleton 是具有相同生命周期的。
如果需要有Scoped生命周期的实例,你需要通过serviceProvider创建一个IServiceScope实例,然后通过该实例获取到的服务实例会跟着IServiceScope一同销毁从而达到Scoped生命周期。
ServiceCollection serviceCollection = new ServiceCollection();serviceCollection.AddSingleton<MySingletonClass>();serviceCollection.AddScoped<MyScopedClass>();serviceCollection.AddTransient<MyTransientClass >();var servicepProvider = serviceCollection.BuildServiceProvider();using (IServiceScope scope = servicepProvider.CreateScope(), scope2 = servicepProvider.CreateScope()){ var scopeObj1 = scope.ServiceProvider.GetService<MyScopedClass>(); var scopeObj2 = scope2.ServiceProvider.GetService<MyScopedClass>(); Console.WriteLine(object.ReferenceEquals(scopeObj1, scopeObj2)); //false}//Scoped Constructor//Scoped Constructor//False//Scoped Dispose//Scoped DisposeConsole.ReadLine();为什么说http request DI 的生命周期是根据RequestServicesFeature来的。通过DI生命周期案例了解到需要创建一个scope生命周期,要有一个IServiceScope实例。
那么在http feature中RequestServicesFeature做了对该接口的封装。也用于提供RequestSerivces服务。
Stack<KeyValuePair<Func<object, Task>, object>>? _onCompleted;堆栈委托public class RequestServicesFeature : IServiceProvidersFeature, IDisposable, IAsyncDisposable{ private IServiceScope? _scope; private readonly HttpContext _context; public RequestServicesFeature(HttpContext context, IServiceScopeFactory? scopeFactory) { _context = context; _scopeFactory = scopeFactory; } public IServiceProvider RequestServices { get { _context.Response.RegisterForDisposeAsync(this); _scope = _scopeFactory.CreateScope(); _requestServices = _scope.ServiceProvider; return _requestServices!; } } /// <inheritdoc /> public ValueTask DisposeAsync() { switch (_scope) { case IAsyncDisposable asyncDisposable: var vt = asyncDisposable.DisposeAsync(); if (!vt.IsCompletedSuccessfully) { return Awaited(this, vt); } vt.GetAwaiter().GetResult(); break; case IDisposable disposable: disposable.Dispose(); break; } }}该类是处理http协议的 ProcessRequests作为重要方法之一,用来使用我们构建好的IHttpApplication 处理request
httpontext的创建,以及我们编排好的http中间件管道都是在这里被执行的。同时调用FireOnCompleted, RequestServicesFeature就是在这里被销毁的。
private async Task ProcessRequests<TContext>(IHttpApplication<TContext> application) where TContext : notnull{ while (_keepAlive) { var context = application.CreateContext(this); // Run the application code for this request await application.ProcessRequestAsync(context); if (_onCompleted?.Count > 0) { await FireOnCompleted(); } application.DisposeContext(context, _applicationException); }}protected Task FireOnCompleted() { var onCompleted = _onCompleted; if (onCompleted?.Count > 0) { return ProcessEvents(this, onCompleted); } return Task.CompletedTask; static async Task ProcessEvents(HttpProtocol protocol, Stack<KeyValuePair<Func<object, Task>, object>> events) { while (events.TryPop(out var entry)) { try { await entry.Key.Invoke(entry.Value); } catch (Exception ex) { protocol.Log.ApplicationError(protocol.ConnectionId, protocol.TraceIdentifier, ex); } } } }_onCompleted;堆栈委托中的HttpProtocol委托堆栈中 RequestServicesFeature 是什么时候被注册进去的呢?
_context.Response.RegisterForDisposeAsync(this); HttpResponseFeature.OnCompleted(callback, state);这里HttpResponseFeature.就是就是HttpProtocol,(HttpProtoccol是个IFeatureCollection接口的实现。)文章中提到的代码,请在source.dot.net快速搜索预览
本文来自博客园,作者:一身大膘,转载请注明原文链接:https://www.cnblogs.com/hts92/p/15856399.html