AspNetCore是否存在旧WebApi IHttpControllerTypeResolver的等价实现?
在ASP.NET Core 2.0中实现仅加载指定单个控制器的最简方案
我明白你在ASP.NET Core 2.0里想实现类似老Web API中自定义控制器发现的需求,确实ASP.NET Core的组件模型和老Web API不太一样,先帮你理清容易混淆的两个核心组件:
- ApplicationPartManager:它是ASP.NET Core中管理应用部件(比如程序集、视图组件、控制器所在模块等)的核心,负责收集应用的所有可发现资源,并协调各类FeatureProvider去提取对应的功能特性。
- ControllerFeatureProvider:它是ApplicationPartManager管理的众多FeatureProvider之一,专门负责从应用部件中识别并提取控制器类型(默认逻辑是扫描所有继承
ControllerBase、带有[ApiController]特性的类)。
老Web API中替换IHttpControllerTypeResolver的逻辑,在ASP.NET Core里对应的就是自定义ControllerFeatureProvider,并通过ApplicationPartManager替换默认的Provider,以此禁用自动发现、仅加载你指定的控制器。
最简实现步骤
1. 自定义ControllerFeatureProvider
创建一个自定义的FeatureProvider,只返回你预先硬编码的控制器类型:
using Microsoft.AspNetCore.Mvc.Controllers; using System.Reflection; public class SingleControllerFeatureProvider : ControllerFeatureProvider { private readonly Type _targetControllerType; public SingleControllerFeatureProvider(Type targetControllerType) { _targetControllerType = targetControllerType; } protected override bool IsController(TypeInfo typeInfo) { // 仅匹配指定的控制器类型,完全禁用默认的自动扫描逻辑 return typeInfo.AsType() == _targetControllerType; } }
2. 配置Mvc服务,替换默认Provider
在Startup.cs中配置Mvc时,通过ConfigureApplicationPartManager移除默认的ControllerFeatureProvider,并添加我们自定义的Provider:
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddMvc() .ConfigureApplicationPartManager(apm => { // 移除默认的控制器发现Provider var defaultProvider = apm.FeatureProviders.OfType<ControllerFeatureProvider>().FirstOrDefault(); if (defaultProvider != null) { apm.FeatureProviders.Remove(defaultProvider); } // 添加自定义Provider,指定要加载的单个控制器 apm.FeatureProviders.Add(new SingleControllerFeatureProvider(typeof(MySpecialController))); }); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } }
3. 你的目标控制器示例
确保你有对应的控制器类(比如MySpecialController):
using Microsoft.AspNetCore.Mvc; [ApiController] [Route("api/[controller]")] public class MySpecialController : ControllerBase { [HttpGet] public IActionResult Get() { return Ok("This is the only controller loaded!"); } }
验证效果
启动Kestrel服务器后,只有MySpecialController会被识别并处理请求,其他任何控制器(哪怕存在于程序集中)都不会被加载,完全实现了硬编码指定单个控制器的需求。
内容的提问来源于stack exchange,提问作者Orion Edwards
相关产品推荐
相关产品推荐

