C# 是否有与旧WebApi IHttpControllerTypeResolver等效的AspNetCore?

C# 是否有与旧WebApi IHttpControllerTypeResolver等效的AspNetCore?,c#,asp.net-core-mvc,asp.net-core-2.0,C#,Asp.net Core Mvc,Asp.net Core 2.0,在WebApi中,您可以替换内置的IHttpControllerTypeResolver,在其中,您可以以自己喜欢的任何方式发现所需的Api控制器 在带有MVC的AspNetCore中,有一堆令人困惑的PartsManager和FeatureManager,其中有些与控制器有关。我所能找到的所有文档和讨论似乎都假设您是一名从事MVC本身工作的开发人员,并且您已经理解ApplicationPartManager和ControllerFeatureProvider之间的区别,而不做任何解释 在最简单

在WebApi中,您可以替换内置的
IHttpControllerTypeResolver
,在其中,您可以以自己喜欢的任何方式发现所需的Api控制器

在带有MVC的AspNetCore中,有一堆令人困惑的PartsManager和FeatureManager,其中有些与控制器有关。我所能找到的所有文档和讨论似乎都假设您是一名从事MVC本身工作的开发人员,并且您已经理解ApplicationPartManager和ControllerFeatureProvider之间的区别,而不做任何解释

在最简单的示例中,我特别想做的是启动一个AspNetCore 2.0 Kestrel服务器的实例,让它只解析预配置的硬编码单控制器。我明确地说,我不想让它这样做,这是正常的发现和所有这些

在WebApi中,您只需执行以下操作:

public class SingleControllerTypeResolver : IHttpControllerTypeResolver
{
    readonly Type m_type;

    public SingleControllerTypeResolver(Type type) => m_type = type;

    public ICollection<Type> GetControllerTypes(IAssembliesResolver assembliesResolver) => new[] { m_type };
}

// ...
// in the configuration:
config.Services.Replace(typeof(IHttpControllerTypeResolver), new SingleControllerTypeResolver(typeof(MySpecialController)))
公共类SingleControllerTypeResolver:IHttpControllerTypeResolver
{
只读类型m_类型;
公共SingleControllerTypeResolver(类型)=>m_类型=类型;
公共ICollection GetControllerTypes(IAssembliesResolver assembliesResolver)=>new[]{m_type};
}
// ...
//在配置中:
替换(typeof(IHttpControllerTypeResolver),新的SingleControllerTypeResolver(typeof(MySpecialController)))

但是,我一直在尝试使用aspnetcore 2获得一个等价的功能,创建该功能似乎很简单,因为您可以从默认的
ControllerFeatureProvider
派生,并覆盖
IsController
以仅识别所需的控制器

public class SingleControllerFeatureProvider : ControllerFeatureProvider {
    readonly Type m_type;

    public SingleControllerTypeResolver(Type type) => m_type = type;

    protected override bool IsController(TypeInfo typeInfo) {
       return base.IsController(typeInfo) && typeInfo == m_type.GetTypeInfo();
    }
}
下一部分是在启动期间用您自己的提供程序替换默认提供程序

public void ConfigureServices(IServiceCollection services) {

    //...

    services
        .AddMvc()
        .ConfigureApplicationPartManager(apm => {
            var originals = apm.FeatureProviders.OfType<ControllerFeatureProvider>().ToList();
            foreach(var original in originals) {
                apm.FeatureProviders.Remove(original);
            }
            apm.FeatureProviders.Add(new SingleControllerFeatureProvider(typeof(MySpecialController)));
        });
        
    //...
}
参考资料

Reference

这看起来不错,但是我想做的是控制控制器的发现并抑制内置发现。看起来SingleControllerFeatureProvider只是要添加我的控制器,而不会影响自动发现的东西?@OrionEdwards discovery正如您所描述的,它的核心与以前完全不同。所有类型都是通过部件零件从其部件中提取的。然后,这些功能将扫描零件并收集与它们相关的类型。
apm.FeatureProviders.OfType().ToList()
-
.ToList()
应添加,以避免枚举错误。@aleha捕获得很好。更新。我感谢你的反馈。
public class SingleControllerFeatureProvider 
    : IApplicationFeatureProvider<ControllerFeature> {
    readonly Type m_type;

    public SingleControllerTypeResolver(Type type) => m_type = type;
    
    public void PopulateFeature(
        IEnumerable<ApplicationPart> parts,
        ControllerFeature feature) {
        if(!feature.Controllers.Contains(m_type)) {
            feature.Controllers.Add(m_type);
        }
    }
}