Lifekind.Scoped 一个请求一个范围是怎么实现的,由ContainerMiddleware 来解决:
Invoke 方法代码:
public async Task Invoke(HttpContext httpContext)
{
if (httpContext.RequestServices != null)
{
throw new Exception("TODO: nested request container scope? this is probably a mistake on your part?");
}
using (var container = RequestServicesContainer.EnsureRequestServices(httpContext, _services))
{
await _next.Invoke(httpContext);
}
}
EnsureRequestServices 方法 核心代码:
return new RequestServicesContainer(httpContext, appServiceScopeFactory, appServiceProvider);
RequestServicesContainer 构造函数代码:
public RequestServicesContainer(
HttpContext context,
IServiceScopeFactory scopeFactory,
IServiceProvider appServiceProvider)
{
if (scopeFactory == null)
{
throw new ArgumentNullException(nameof(scopeFactory));
}
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
Context = context;
PriorAppServices = context.ApplicationServices;
PriorRequestServices = context.RequestServices;
// Begin the scope
Scope = scopeFactory.CreateScope();
Context.ApplicationServices = appServiceProvider;
Context.RequestServices = Scope.ServiceProvider;
}
看一下 扩展方法:
public static class ContainerExtensions
{
public static IApplicationBuilder UseRequestServices(this IApplicationBuilder builder)
{
return builder.UseMiddleware<ContainerMiddleware>();
}
// Review: what do we use these for?
public static IApplicationBuilder UseRequestServices(this IApplicationBuilder builder, IServiceProvider applicationServices)
{
// REVIEW: should this be doing fallback?
builder.ApplicationServices = applicationServices;
return builder.UseMiddleware<ContainerMiddleware>();
}
// Note: Manifests are lost after UseServices, services are flattened into ApplicationServices
public static IApplicationBuilder UseServices(this IApplicationBuilder builder, IEnumerable<IServiceDescriptor> applicationServices)
{
return builder.UseServices(services => services.Add(applicationServices));
}
public static IApplicationBuilder UseServices(this IApplicationBuilder builder, Action<IServiceCollection> configureServices)
{
return builder.UseServices(serviceCollection =>
{
configureServices(serviceCollection);
return serviceCollection.BuildServiceProvider();
});
}
public static IApplicationBuilder UseServices(this IApplicationBuilder builder, Func<IServiceCollection, IServiceProvider> configureServices)
{
// Import services from hosting/KRE as fallback
var serviceCollection = HostingServices.Create(builder.ApplicationServices);
builder.ApplicationServices = configureServices(serviceCollection);
return builder.UseMiddleware<ContainerMiddleware>();
}
}
当调用 UseServices 方法的时候 就使用了这一中间件。
理论上应该是最靠前的一个中间件。
浙公网安备 33010602011771号