是否有旧的WebApi IHttpControllerTypeResolver的AspNetCore?

时间:2018-05-16 23:45:31

标签: c# asp.net-core-mvc asp.net-core-2.0

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

在使用MVC的AspNetCore中,有一个令人困惑的零件管理器和FeatureManagers纠结在一起,其中某处与控制器有关。我能够找到的所有文档和讨论似乎都假设您是一名开发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)))

但是我一直试图使用aspnetcore 2

来获得等价物

1 个答案:

答案 0 :(得分: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>();
            foreach(var original in originals) {
                apm.FeatureProviders.Remove(original);
            }
            apm.FeatureProviders.Add(new SingleControllerFeatureProvider(typeof(MySpecialController)));
        });

    //...
}

如果覆盖默认实现不够明确,那么您可以直接实施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);
        }
    }
}

参考Application Parts in ASP.NET Core: Application Feature Providers
参考Discovering Generic Controllers in ASP.NET Core