UseRouting內部:
public static IApplicationBuilder UseRouting(this IApplicationBuilder builder) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } //在調用UseEndpoint之前驗證AddRouting服務是否已完成
//我們使用RoutingMarkerService來確保是否添加了所有服務。
//AddRouting服務在Program類的ConfigureWebHostDefaults調用后添加。
VerifyRoutingServicesAreRegistered(builder); //VerifyRoutingServicesAreRegistered 內部 //if (app.ApplicationServices.GetService(typeof(RoutingMarkerService)) == null) //{ // throw new InvalidOperationException(Resources.FormatUnableToFindServices( // nameof(IServiceCollection), // nameof(RoutingServiceCollectionExtensions.AddRouting), // "ConfigureServices(...)")); //} //初始化數據源 var endpointRouteBuilder = new DefaultEndpointRouteBuilder(builder); //DefaultEndpointRouteBuilder構造類內部 //public DefaultEndpointRouteBuilder(IApplicationBuilder applicationBuilder) //{ // ApplicationBuilder = applicationBuilder ?? throw new ArgumentNullException(nameof(applicationBuilder)); // DataSources = new List<EndpointDataSource>(); //} //EndpointRouteBuilder為字符串常量 __EndpointRouteBuilder //// builder.Properties["__EndpointRouteBuilder"] = endpointRouteBuilder; builder.Properties[EndpointRouteBuilder] = endpointRouteBuilder; //操作完成后對此實例引用 return builder.UseMiddleware<EndpointRoutingMiddleware>(endpointRouteBuilder); }
UseEndpoints內部:
public static IApplicationBuilder UseEndpoints(this IApplicationBuilder builder, Action<IEndpointRouteBuilder> configure) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (configure == null) { throw new ArgumentNullException(nameof(configure)); } //在調用UseEndpoint之前驗證AddRouting服務是否已完成
//我們使用RoutingMarkerService來確保是否添加了所有服務。
//AddRouting服務在Program類的ConfigureWebHostDefaults調用后添加。
//所以在調用UseEndpoint之前 必須要先調用UseRouting,否則報錯。 VerifyRoutingServicesAreRegistered(builder); //VerifyRoutingServicesAreRegistered方法內部 //private static void VerifyRoutingServicesAreRegistered(IApplicationBuilder app) //{ // if (app.ApplicationServices.GetService(typeof(RoutingMarkerService)) == null) // { // throw new InvalidOperationException(Resources.FormatUnableToFindServices( // nameof(IServiceCollection), // nameof(RoutingServiceCollectionExtensions.AddRouting), // "ConfigureServices(...)")); // } //} //驗證端點路由中間件是否已注冊 VerifyEndpointRoutingMiddlewareIsRegistered(builder, out var endpointRouteBuilder); //VerifyEndpointRoutingMiddlewareIsRegistered方法內部 //private static void VerifyEndpointRoutingMiddlewareIsRegistered(IApplicationBuilder app, out DefaultEndpointRouteBuilder endpointRouteBuilder) //{ // if (!app.Properties.TryGetValue(EndpointRouteBuilder, out var obj)) // { // var message = // $"{nameof(EndpointRoutingMiddleware)} matches endpoints setup by {nameof(EndpointMiddleware)} and so must be added to the request " + // $"execution pipeline before {nameof(EndpointMiddleware)}. " + // $"Please add {nameof(EndpointRoutingMiddleware)} by calling '{nameof(IApplicationBuilder)}.{nameof(UseRouting)}' inside the call " + // $"to 'Configure(...)' in the application startup code."; // throw new InvalidOperationException(message); // } // //如果此處轉換失敗,程序會出錯。 // endpointRouteBuilder = (DefaultEndpointRouteBuilder)obj; // // //此檢查處理在兩者之間調用Map或其他分叉管道的情況 // if (!object.ReferenceEquals(app, endpointRouteBuilder.ApplicationBuilder)) // { // var message = // $"The {nameof(EndpointRoutingMiddleware)} and {nameof(EndpointMiddleware)} must be added to the same {nameof(IApplicationBuilder)} instance. " + // $"To use Endpoint Routing with 'Map(...)', make sure to call '{nameof(IApplicationBuilder)}.{nameof(UseRouting)}' before " + // $"'{nameof(IApplicationBuilder)}.{nameof(UseEndpoints)}' for each branch of the middleware pipeline."; // throw new InvalidOperationException(message); // } //} configure(endpointRouteBuilder); //我們正在將數據源注冊到一個全局集合中 //可用於發現端點或生成URL。 //每個中間件都有自己的數據源集合,所有這些數據源也 //被添加到全局集合中。 var routeOptions = builder.ApplicationServices.GetRequiredService<IOptions<RouteOptions>>(); foreach (var dataSource in endpointRouteBuilder.DataSources) { routeOptions.Value.EndpointDataSources.Add(dataSource); } //操作完成后對此實例引用 return builder.UseMiddleware<EndpointMiddleware>(); }