在上节中我们已经得知 WebApplication
实现了 IApplicationBuilder
,我们浅谈了其pipe特质和构建方法,本节中将深入了解 ApplicationBuilder
以窥探 IApplicationBuilder
真相
public interface IApplicationBuilder
{
IServiceProvider ApplicationServices { get; set; }
IFeatureCollection ServerFeatures { get; }
IDictionary<string, object?> Properties { get; }
IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware);
IApplicationBuilder New();
RequestDelegate Build();
}
管道机制
该机制是.NET最关键的机制之一,贯彻整个APP生命周期,但他的实现,简单巧妙的让人惊叹。
首先在内部维护了一个 Func<RequestDelegate, RequestDelegate>
集合
private readonly List<Func<RequestDelegate, RequestDelegate>> _components = new List<Func<RequestDelegate, RequestDelegate>>();
Func<RequestDelegate, RequestDelegate>
还有一个美腻的别名叫:中间件,UseMiddleware
的本质,就是 IApplicationBuilder.Use
,调用 Use
其实就是添加一个中间件到集合
public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
{
this._components.Add(middleware);
return (IApplicationBuilder) this;
}
最终在 Build
生成此应用程序用于处理HTTP请求的委托。
public RequestDelegate Build()
{
RequestDelegate requestDelegate = (RequestDelegate) (context =>
{
Endpoint endpoint = context.GetEndpoint();
if (endpoint?.RequestDelegate != null)
throw new InvalidOperationException("The request reached the end of the pipeline without executing the endpoint: '" + endpoint.DisplayName + "'. Please register the EndpointMiddleware using 'IApplicationBuilder.UseEndpoints(...)' if using routing.");
context.Response.StatusCode = 404;
return Task.CompletedTask;
});
for (int index = this._components.Count - 1; index >= 0; --index)
requestDelegate = this._components[index](requestDelegate);
return requestDelegate;
}
为什么要倒着循环呢?这是因为在ASP.NET Core中,中间件的执行顺序是按照它们在ApplicationBuilder
中注册的顺序来决定的。后注册的中间件会在前注册的中间件之前执行,这就是经典的洋葱模型
Properties&Features
Properties
是一个字典,用于在中间件之间共享数据。
public IDictionary<string, object?> Properties { get; }
为了防止在中间件中修改 ApplicationBuilder
对象的状态,实现了一个原型模型:仅复制 Properties
public IApplicationBuilder New() => (IApplicationBuilder) new ApplicationBuilder(this);
private ApplicationBuilder(ApplicationBuilder builder) => this.Properties = (IDictionary<string, object>) new CopyOnWriteDictionary<string, object>(builder.Properties, (IEqualityComparer<string>) StringComparer.Ordinal);
Features
用于获取应用程序Server提供的一组HTTP features,如果程序没有指定Server,则返回空集合
public interface IFeatureCollection : IEnumerable<KeyValuePair<Type, object>>, IEnumerable
在 ApplicationBuilder
中 Features
直接引用 Properties
,他们两者基本等价。而在 WebApplication
中,通过 IServer
提供
IFeatureCollection ServerFeatures => this._host.Services.GetRequiredService<IServer>().Features;
IServer
是服务器知识,看同学们述求,考虑是否讲
IServiceProvider
IServiceProvider
用于访问应用程序服务容器,位于 System
命名空间,在整个 .NET 中举重若轻。它的功能非常简洁,只做一件事情,仅有一个方法,用于从服务容器中获取给定服务的实现。
public interface IServiceProvider
{
/// <summary>Gets the service object of the specified type.</summary>
/// <param name="serviceType">An object that specifies the type of service object to get.</param>
/// <returns>A service object of type <paramref name="serviceType" />.
/// -or-
/// <see langword="null" /> if there is no service object of type <paramref name="serviceType" />.</returns>
object? GetService(Type serviceType);
}
服务容器化,横空出世;依赖注入,孕育而生
标签:ApplicationBuilder,object,中间件,IApplicationBuilder,Properties,详解,public From: https://www.cnblogs.com/xiaolipro/p/17815831.html