Discovering Generic Controllers in ASP.NET Core

前端 未结 4 1572
时光取名叫无心
时光取名叫无心 2020-12-03 01:18

I am trying to create a generic controller like this:

[Route(\"api/[controller]\")]
public class OrdersController : Controller where T : IOrder
{
           


        
4条回答
  •  天命终不由人
    2020-12-03 02:13

    Short Answer

    Implement IApplicationFeatureProvider.

    Question and Answer

    Does anyone know what "service" interface is responsible for [discovering all available controllers]?

    The ControllerFeatureProvider is responsible for that.

    And does anyone know of a way to make ASP.NET Core "dump" the names of all the controllers it discovered?

    Do that within ControllerFeatureProvider.IsController(TypeInfo typeInfo).

    Example

    MyControllerFeatureProvider.cs

    using System;
    using System.Linq;
    using System.Reflection;
    using Microsoft.AspNetCore.Mvc.Controllers;
    
    namespace CustomControllerNames 
    {
        public class MyControllerFeatureProvider : ControllerFeatureProvider 
        {
            protected override bool IsController(TypeInfo typeInfo)
            {
                var isController = base.IsController(typeInfo);
    
                if (!isController)
                {
                    string[] validEndings = new[] { "Foobar", "Controller`1" };
    
                    isController = validEndings.Any(x => 
                        typeInfo.Name.EndsWith(x, StringComparison.OrdinalIgnoreCase));
                }
    
                Console.WriteLine($"{typeInfo.Name} IsController: {isController}.");
    
                return isController;
            }
        }
    }
    

    Register it during startup.

    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddMvcCore()
            .ConfigureApplicationPartManager(manager => 
            {
                manager.FeatureProviders.Add(new MyControllerFeatureProvider());
            });
    }
    

    Here is some example output.

    MyControllerFeatureProvider IsController: False.
    OrdersFoobar IsController: True.
    OrdersFoobarController`1 IsController: True.
    Program IsController: False.
    <>c__DisplayClass0_0 IsController: False.
    <>c IsController: False.
    

    And here is a demo on GitHub. Best of luck.

    Edit - Adding Versions

    .NET Version

    > dnvm install "1.0.0-rc2-20221" -runtime coreclr -architecture x64 -os win -unstable
    

    NuGet.Config

    
    
      
        
          
      
    
    

    .NET CLI

    > dotnet --info
    .NET Command Line Tools (1.0.0-rc2-002429)
    
    Product Information:
     Version:     1.0.0-rc2-002429
     Commit Sha:  612088cfa8
    
    Runtime Environment:
     OS Name:     Windows
     OS Version:  10.0.10586
     OS Platform: Windows
     RID:         win10-x64
    

    Restore, Build, and Run

    > dotnet restore
    > dotnet build
    > dotnet run
    

    Edit - Notes on RC1 vs RC2

    This might not be possible is RC1, because DefaultControllerTypeProvider.IsController() is marked as internal.

提交回复
热议问题