Aspnet Core 3 端点路由配置源代码
学习:《asp.net core 3.x Endpoint终结点路由1-基本介绍和使用》、《ASP.NET Core 2.2 : 十六.扒一扒新的Endpoint路由方案》
《.netcore入门16:aspnetcore之终结点路由工作原理》、《.netcore入门13:aspnetcore源码之如何在程序启动时将Controller里的Action自动扫描封装成Endpoint》。
------------------------------------------------------------------------------------------
1、Aspnet Core 3 端点路由配置,在 Startup 类的 Configure 方法中:
app.UseRouting(); //必须放在后者之前,而且 必须是 注册在 相同的 App(IApplicationBuilder),代码注释中有特别说明 !
app.UseEndpoints( Action<IEndpointRouteBuilder> configure);
从代码中看出一点:UseRouting() ,会在属性中new一个IEndpointRouteBuilder:
app.Properties[EndpointRouteBuilder] = new DefaultEndpointRouteBuilder(builder);
UseEndpoints( Action<IEndpointRouteBuilder> configure) 执行时,会将前面New的 DefaultEndpointRouteBuilder 实例取出,并进一步配置它: configure(EndpointRouteBuilder实例) 。
2、接口 IEndpointRouteBuilder (V3.0才有,另外,还有一个 IRouteBuilder),
有一个属性: DataSources (ICollection<EndpointDataSource>) ,定义源代码:https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.aspnetcore.routing.iendpointroutebuilder?view=aspnetcore-3.1 ; EndpointDataSource 只有一个属性 Endpoints ( IReadOnlyList<Endpoint> )
重点是它的扩展方法。如:
MapControllers(IEndpointRouteBuilder),
MapControllerRoute(IEndpointRouteBuilder, String, String, Object, Object, Object) 即 name
, pattern
, defaults
, constraints
, 与 dataTokens
.
=====================================================================================
aspnetcore/src/Http/Routing/src/Builder/EndpointRoutingApplicationBuilderExtensions.cs 源代码地址:
{
if (builder == null) { throw new ArgumentNullException(nameof(builder)); }
VerifyRoutingServicesAreRegistered(builder);
var endpointRouteBuilder = new DefaultEndpointRouteBuilder(builder);
builder.Properties[EndpointRouteBuilder] = endpointRouteBuilder;
return builder.UseMiddleware<EndpointRoutingMiddleware>(endpointRouteBuilder);
}
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)); }
VerifyRoutingServicesAreRegistered(builder); //此方法中用到 RoutingMarkerService 标识类
VerifyEndpointRoutingMiddlewareIsRegistered(builder, out var endpointRouteBuilder);
configure(endpointRouteBuilder);
// Yes, this mutates an IOptions. We're registering data sources in a global collection which
// can be used for discovery of endpoints or URL generation.
// Each middleware gets its own collection of data sources, and all of those data sources also
// get added to a global collection.
var routeOptions = builder.ApplicationServices.GetRequiredService<IOptions<RouteOptions>>();
foreach (var dataSource in endpointRouteBuilder.DataSources)
{
routeOptions.Value.EndpointDataSources.Add(dataSource);
}
return builder.UseMiddleware<EndpointMiddleware>();
}
internal class DefaultEndpointRouteBuilder : IEndpointRouteBuilder
{
public DefaultEndpointRouteBuilder(IApplicationBuilder applicationBuilder)
{
ApplicationBuilder = applicationBuilder ?? throw new ArgumentNullException(nameof(applicationBuilder));
DataSources = new List<EndpointDataSource>();
}
public IApplicationBuilder ApplicationBuilder { get; }
public IApplicationBuilder CreateApplicationBuilder() => ApplicationBuilder.New();
public ICollection<EndpointDataSource> DataSources { get; }
public IServiceProvider ServiceProvider => ApplicationBuilder.ApplicationServices;
}
EndpointDataSource https://docs.microsoft.com/zh-cn/dotnet/api/microsoft.aspnetcore.routing.endpointdatasource?view=aspnetcore-3.1
Endpoints |