日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

.NET 8 IEndpointRouteBuilder详解

發布時間:2023/11/16 asp.net 57 coder
生活随笔 收集整理的這篇文章主要介紹了 .NET 8 IEndpointRouteBuilder详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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<string>) EndpointRouteBuilderExtensions.GetVerb, handler);
}

? 我們已經解釋過 IEndpointRouteBuilder 的定義了,即為程序定義路由構建的約定。這次看到的是他的拓展方法 Map ,該方法是諸如 MapGetMapPostMapPutMapDeleteMapPatchMapMethods 的底層方法:

? 他的實現就是為了給IEndpointRouteBuilderDataSources 添加一個 RouteEndpointDataSource

private static RouteHandlerBuilder Map(this IEndpointRouteBuilder endpoints, RoutePattern pattern, Delegate handler, IEnumerable<string> httpMethods, bool isFallback)
{
	return endpoints.GetOrAddRouteEndpointDataSource().AddRouteHandler(pattern, handler, httpMethods, isFallback, RequestDelegateFactory.InferMetadata, RequestDelegateFactory.Create);
}

? RouteEndpointDataSource 繼承自 EndpointDataSource,提供一組RouteEndpoint

public override IReadOnlyList<RouteEndpoint> Endpoints
{
	get
	{
		RouteEndpoint[] array = new RouteEndpoint[_routeEntries.Count];
		for (int i = 0; i < _routeEntries.Count; i++)
		{
			array[i] = (RouteEndpoint)CreateRouteEndpointBuilder(_routeEntries[i]).Build();
		}
		return array;
	}
}

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集合,包含描述、標簽、權限等數據,這一般是框架用到的,后面會再次見到它。重點是 RequestDelegateHttpContext 首次登場,相信有過Web開發經驗的同學熟悉的不能再熟悉。該委托其實就是一個Func<HttpContext, Task>,用于處理HTTP請求,由于TAP的普及,所以返回的Task

public delegate Task RequestDelegate(HttpContext context);

? Endpoint 一般由 EndpointBuilder 構建,他能夠額外組裝Filter

public IList<Func<EndpointFilterFactoryContext, EndpointFilterDelegate, EndpointFilterDelegate>> FilterFactories

EndpointDataSource

? 經過對 MapGet 的剖析我們最終發現,所有的終結點都被掛載在了 EndpointDataSource

public abstract IReadOnlyList<Endpoint> Endpoints { get; }
public virtual IReadOnlyList<Endpoint> GetGroupedEndpoints(RouteGroupContext context)

? 除了被大家熟悉的 Endpoints 還提供了一個方法 GetGroupedEndpoints:在給定指定前綴和約定的情況下,獲取此EndpointDataSource 的所有 Endpoint的。

public virtual IReadOnlyList<Endpoint> GetGroupedEndpoints(RouteGroupContext context)
{
	IReadOnlyList<Endpoint> endpoints = Endpoints;
	RouteEndpoint[] array = new RouteEndpoint[endpoints.Count];
	for (int i = 0; i < endpoints.Count; i++)
	{
		Endpoint endpoint = endpoints[i];
		if (!(endpoint is RouteEndpoint routeEndpoint))
		{
			throw new NotSupportedException(Resources.FormatMapGroup_CustomEndpointUnsupported(endpoint.GetType()));
		}
		RoutePattern routePattern = RoutePatternFactory.Combine(context.Prefix, routeEndpoint.RoutePattern);
		RouteEndpointBuilder routeEndpointBuilder = new RouteEndpointBuilder(routeEndpoint.RequestDelegate, routePattern, routeEndpoint.Order)
		{
			DisplayName = routeEndpoint.DisplayName,
			ApplicationServices = context.ApplicationServices
		};
		foreach (Action<EndpointBuilder> convention in context.Conventions)
		{
			convention(routeEndpointBuilder);
		}
		foreach (object metadatum in routeEndpoint.Metadata)
		{
			routeEndpointBuilder.Metadata.Add(metadatum);
		}
		foreach (Action<EndpointBuilder> finallyConvention in context.FinallyConventions)
		{
			finallyConvention(routeEndpointBuilder);
		}
		array[i] = (RouteEndpoint)routeEndpointBuilder.Build();
	}
	return array;
}

? 通過剖析 RouteGroupContext,很容易發覺,Prefix 是一個路由前綴,ConventionsFinallyConventions 是兩個約定hook。它專為 RouteEndpoint 獨有,通過 GetGroupedEndpoints 方法,組的前綴和約定,會作用到每一個路由終結點。

public sealed class RouteGroupContext
{
    public required RoutePattern Prefix { get; init; }
    public IReadOnlyList<Action<EndpointBuilder>> Conventions { get; init; } = Array.Empty<Action<EndpointBuilder>>();
    public IReadOnlyList<Action<EndpointBuilder>> FinallyConventions { get; init; } = Array.Empty<Action<EndpointBuilder>>();
}

總結

以上是生活随笔為你收集整理的.NET 8 IEndpointRouteBuilder详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。