如何通过Scrutor向IEndpointRouteBuilder注册最小API端点
问题
已创建IEndpoint接口及其实现类TodoApi,且通过Scrutor扫描加载了所有实现IEndpoint的类作为服务。现在希望在Program.cs的WebApplication实例中注册这些端点,曾尝试使用app.MapGroup但不符合需求,请问该如何操作?
相关代码如下:
public interface IEndpoint { RouteGroupBuilder MapRoutes(IEndpointRouteBuilder routes); }
public class TodoApi : IEndpoint { public RouteGroupBuilder MapRoutes(IEndpointRouteBuilder routes) { var group = routes.MapGroup("/todo"); group.MapGet("/", () => "Hello"); return group; } }
var endpointServices = new ServiceCollection(); endpointServices.Scan(scan => scan.FromAssemblyOf<IEndpoint>() .AddClasses(classes => classes.AssignableTo<IEndpoint>()) .AsImplementedInterfaces() );
var app = builder.Build(); foreach (var item in endpointServices) { if (item.ImplementationInstance is IEndpoint endpoint) { // 此处该如何处理? } }
解决方案
你当前的问题核心是错误地遍历ServiceCollection而非从已构建的服务提供者中获取IEndpoint实例——ServiceCollection仅用于注册服务,此时并未创建服务实例,ImplementationInstance会是null。正确做法是从WebApplication的服务容器中取出所有IEndpoint实例,再调用它们的路由注册方法。
修正步骤如下:
- 直接使用应用的服务容器注册
IEndpoint实现类(不要单独创建ServiceCollection,否则这些服务不会被WebApplication加载):
// 替换单独创建的ServiceCollection,直接用builder.Services完成注册 builder.Services.Scan(scan => scan.FromAssemblyOf<IEndpoint>() .AddClasses(classes => classes.AssignableTo<IEndpoint>()) .AsImplementedInterfaces() );
- 构建WebApplication后,从服务容器中获取所有
IEndpoint实例并执行路由注册:
var app = builder.Build(); // 获取所有已注册的IEndpoint实例 var endpoints = app.Services.GetServices<IEndpoint>(); foreach (var endpoint in endpoints) { endpoint.MapRoutes(app); } // 后续中间件配置、启动应用等逻辑 app.Run();
这样每个IEndpoint实现类的MapRoutes方法都会被触发,自动完成对应路由组和端点的注册,完全匹配你的需求。
内容的提问来源于stack exchange,提问作者Nasim Uddin
相关产品推荐
相关产品推荐

