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

Ori*_*rds 6 c# asp.net-core-mvc asp.net-core-2.0

在 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)))
Run Code Online (Sandbox Code Playgroud)

但是我一直试图使用 aspnetcore 2 获得等效的结果

Nko*_*osi 7

创建该功能似乎很简单,因为您可以从默认值派生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();
    }
}
Run Code Online (Sandbox Code Playgroud)

下一部分是在启动过程中将默认提供程序替换为您自己的提供程序。

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)));
        });
        
    //...
}
Run Code Online (Sandbox Code Playgroud)

如果重写默认实现被认为不够明确,那么您可以IApplicationFeatureProvider<ControllerFeature>直接实现并PopulateFeature自己提供。

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

ASP.NET Core 中的参考应用程序部件:应用程序功能提供程序
参考在 ASP.NET Core 中发现通用控制器