.NET Core 6 如何在IEndpoint实现类Map方法中使用ApiVersionSet
实现方法
你可以根据自己的架构需求选择以下两种无侵入的实现方案:
方案1:扩展接口方法参数,传递映射上下文
这是性能最优、逻辑最直白的实现,适合仅在端点映射环节使用公共配置的场景。
- 调整
IEndpoint接口定义,增加公共配置参数:
public interface IEndpoint { void Map(IEndpointRouteBuilder builder, ApiVersionSet versionSet); }
- 修改
MapEndpoints扩展方法,在方法内部构建全局版本集合并传递给所有端点:
public static IEndpointRouteBuilder MapEndpoints(this IEndpointRouteBuilder builder) { // 构建全局共用的API版本集 ApiVersionSet versionSet = builder.NewApiVersionSet() .HasApiVersion(new ApiVersion(1.0)) .ReportApiVersions() .Build(); using IServiceScope scope = builder.ServiceProvider.CreateScope(); IEnumerable<IEndpoint> endpoints = scope.ServiceProvider.GetServices<IEndpoint>(); foreach (IEndpoint endpoint in endpoints) { endpoint.Map(builder, versionSet); } return builder; }
- 调整所有
IEndpoint实现类的Map方法签名,直接使用传入的versionSet即可,修正原代码中WithName后多余分号的语法错误:
public class CountryEndpoint : IEndpoint { public void Map(IEndpointRouteBuilder builder, ApiVersionSet versionSet) { builder.MapGet("countries", async ([FromServices] IService service) => { List<Country> countries = await service.GetCountries(); return Results.Ok(countries); }) .WithName("Countries") .WithApiVersionSet(versionSet) .MapToApiVersion(1.0); } }
后续如果需要新增全局通用配置(比如跨域策略、全局授权过滤),只需要在方法参数中新增对应字段即可,不需要调整依赖注入规则。
方案2:注册为单例服务,通过构造函数注入
如果你不想修改IEndpoint接口定义,可以将版本集注册到DI容器,在端点实现类中注入使用。
- 在
Program.cs的服务配置阶段,注册延迟加载的版本集单例,避免生命周期解析错误:
builder.Services.AddSingleton(sp => { return new Lazy<ApiVersionSet>(() => { var routeBuilder = sp.GetRequiredService<IEndpointRouteBuilder>(); return routeBuilder.NewApiVersionSet() .HasApiVersion(new ApiVersion(1.0)) .ReportApiVersions() .Build(); }); });
- 在端点实现类中注入服务使用:
public class CountryEndpoint : IEndpoint { private readonly Lazy<ApiVersionSet> _versionSet; public CountryEndpoint(Lazy<ApiVersionSet> versionSet) { _versionSet = versionSet; } public void Map(IEndpointRouteBuilder builder) { builder.MapGet("countries", async ([FromServices] IService service) => { List<Country> countries = await service.GetCountries(); return Results.Ok(countries); }) .WithName("Countries") .WithApiVersionSet(_versionSet.Value) .MapToApiVersion(1.0); } }
注意:
ApiVersionSet必须依托IEndpointRouteBuilder实例构建,而该实例在应用启动完成后才可用,因此用Lazy<>包装做延迟加载,避免启动时抛出服务解析异常。
方案选型建议
- 仅在端点映射逻辑中使用版本集配置时,优先选方案1,无额外DI开销,逻辑更直观
- 除端点映射外,其他业务服务也需要读取版本集配置时,选方案2更合理
内容的提问来源于stack exchange,提问作者Miguel Moura
相关产品推荐
相关产品推荐

