Map
经过对 WebApplication
的初步剖析,我们已经大致对Web应用的骨架有了一定了解,现在我们来看一下Hello World案例中仅剩的一条代码:
app.MapGet("/", () => "Hello World!"); // 3 添加路由处理
老规矩,看签名:
public static RouteHandlerBuilder MapGet(this IEndpointRouteBuilder endpoints,
[StringSyntax("Route")] string pattern,Delegate handler){
return endpoints.MapMethods(pattern, (IEnumerable) EndpointRouteBuilderExtensions.GetVerb, handler);
}
我们已经解释过 IEndpointRouteBuilder
的定义了,即为程序定义路由构建的约定。这次看到的是他的拓展方法 Map
,该方法是诸如 MapGet
、MapPost
、MapPut
、MapDelete
、MapPatch
、MapMethods
的底层方法:
他的实现就是为了给IEndpointRouteBuilder
的 DataSources
添加一个 RouteEndpointDataSource
private static RouteHandlerBuilder Map(this IEndpointRouteBuilder endpoints, RoutePattern pattern, Delegate handler, IEnumerable httpMethods, bool isFallback)
{
return endpoints.GetOrAddRouteEndpointDataSource().AddRouteHandler(pattern, handler, httpMethods, isFallback, RequestDelegateFactory.InferMetadata, RequestDelegateFactory.Create);
}
RouteEndpointDataSource
继承自 EndpointDataSource
,提供一组RouteEndpoint
public override IReadOnlyList Endpoints
{
get
{
RouteEndpoin服务器托管网t[] array = new RouteEndpoint[_routeEntries.Count];
for (int i = 0; i
Endpoint
RouteEndpoint
继承自 Endpoint
。多了一个 RoutePattern
属性,用于路由匹配,支持模式路由。还有一个 Order
属性,用于处理多匹配源下的优先级问题。
public sealed class RouteEndpoint : Endpoint
{
public int Order { get; }
public RoutePattern RoutePattern { get; }
}
Endpoint
是一个应用程序中路的一个逻辑终结点。
public string? DisplayName { get; } // 终结点名称
public EndpointMetadataCollection Metadata { get; } // 元数据
public RequestDelegate? RequestDelegate { get; } // 请求委服务器托管网托
其中 Metadata
就是一个object集合,包含描述、标签、权限等数据,这一般是框架用到的,后面会再次见到它。重点是 RequestDelegate
:HttpContext
首次登场,相信有过Web开发经验的同学熟悉的不能再熟悉。该委托其实就是一个Func
,用于处理HTTP请求,由于TAP的普及,所以返回的Task
。
public delegate Task RequestDelegate(HttpContext context);
Endpoint
一般由 EndpointBuilder
构建,他能够额外组装Filter
public IList> FilterFactories
EndpointDataSource
经过对 MapGet
的剖析我们最终发现,所有的终结点都被挂载在了 EndpointDataSource
public abstract IReadOnlyList Endpoints { get; }
public virtual IReadOnlyList GetGroupedEndpoints(RouteGroupContext context)
除了被大家熟悉的 Endpoints
还提供了一个方法 GetGroupedEndpoints
:在给定指定前缀和约定的情况下,获取此EndpointDataSource
的所有 Endpoint
的。
public virtual IReadOnlyList GetGroupedEndpoints(RouteGroupContext context)
{
IReadOnlyList endpoints = Endpoints;
RouteEndpoint[] array = new RouteEndpoint[endpoints.Count];
for (int i = 0; i convention in context.Conventions)
{
convention(routeEndpointBuilder);
}
foreach (object metadatum in routeEndpoint.Metadata)
{
routeEndpointBuilder.Metadata.Add(metadatum);
}
foreach (Action finallyConvention in context.FinallyConventions)
{
finallyConvention(routeEndpointBuilder);
}
array[i] = (RouteEndpoint)routeEndpointBuilder.Build();
}
return array;
}
通过剖析 RouteGroupContext
,很容易发觉,Prefix
是一个路由前缀,Conventions
和 FinallyConventions
是两个约定hook。它专为 RouteEndpoint
独有,通过 GetGroupedEndpoints
方法,组的前缀和约定,会作用到每一个路由终结点。
public sealed class RouteGroupContext
{
public required RoutePattern Prefix { get; init; }
public IReadOnlyList> Conventions { get; init; } = Array.Empty>();
public IReadOnlyList> FinallyConventions { get; init; } = Array.Empty>();
}
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
相关推荐: 基于LangChain的LLM应用开发3——记忆
此情可待成追忆,只是当时已惘然。我们人类会有很多或美好或痛苦的回忆,有的回忆会渐渐模糊,有的回忆午夜梦醒,会浮上心头。 然而现在的大语言模服务器托管网型都是没有记忆的,都是无状态的,大语言模型自身不会记住和你对话之间的历史消息。根本用不着“时时勤拂拭”,天然就…