c# - 如何在程序集中找到所有类,这些类是通用抽象类的实例并实现某个接口(interface)

标签 c# asp.net .net asp.net-core .net-core

如何在程序集中找到作为通用抽象类实例并实现特定接口(interface)的所有类?

注意:
该接口(interface)也可以在从另一个实现该接口(interface)的类继承的类中实现。

一个具体的例子:
我有以下界面和中间件类:

public interface IHttpHandler
{
    bool IsReusable { get; }
    void ProcessRequest(HttpContext context);
}

public abstract class HandlerMiddleware<T> where T: IHttpHandler
{

    private readonly RequestDelegate _next;

    public HandlerMiddleware()
    { }

    public HandlerMiddleware(RequestDelegate next)
    {
        _next = next;
    }


    public async Task Invoke(HttpContext context)
    {    
        await SyncInvoke(context);
    }


    public Task SyncInvoke(HttpContext context)
    {
        // IHttpHandler handler = (IHttpHandler)this;
        T handler = System.Activator.CreateInstance<T>();

        handler.ProcessRequest(context);
        return Task.CompletedTask;
    }


} // End Abstract Class HandlerMiddleware

如何找到所有实现抽象类的类,如 HelloWorldHandler,并实现 IHttpHandler。

请注意,HandlerMiddleware 是通用的。
它应该找到所有处理程序,例如HelloWorldHandler1 和 HelloWorldHandler2。

[HandlerPath("/hello")]
public class HelloWorldHandler 
    : HandlerMiddleware<HelloWorldHandler>, IHttpHandler
{
    public HelloWorldHandler() :base() { }
    public HelloWorldHandler(RequestDelegate next):base(next) { }

    void IHttpHandler.ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";

        //await context.Response.WriteAsync("Hello World!");
        byte[] buffer = System.Text.Encoding.UTF8.GetBytes("hello world");
        context.Response.Body.Write(buffer, 0, buffer.Length);
    }

    bool IHttpHandler.IsReusable
    {
        get
        {
            return false;
        }
    }

}

如果该方法也找到此构造,则加分:

[HandlerPath("/hello2")]
public class HelloWorldHandler2
: HandlerMiddleware<Middleman>
{

    public HelloWorldHandler2() :base() { }
    public HelloWorldHandler2(RequestDelegate next):base(next) { }

}


public class Middleman
    : IHttpHandler
{
    bool IHttpHandler.IsReusable => throw new NotImplementedException();

    void IHttpHandler.ProcessRequest(HttpContext context)
    {
        throw new NotImplementedException();
    }
}

最佳答案

您的问题实际上很难理解。
问题是您的类派生自泛型类,其泛型参数实现了 IHttpHandler。

您需要获取继承的(基)类型(因为您继承自它)。
那是一个通用类型,所以你需要检查它是否是一个通用类型。
如果是,则需要获取泛型类型(GetGenericTypeDefinition)。
然后你需要检查泛型类型是否是类型 HandlerMiddleware<
然后你需要从泛型类型中获取参数。
然后你需要检查第一个泛型参数(如果它有的话)。
然后您需要检查该通用参数的类型(或其派生基础)是否实现了相关接口(interface)。

所以在你的情况下:

var ls = FindDerivedTypes(t.Assembly, typeof(HandlerMiddleware<>), typeof(IHttpHandler));
        System.Console.WriteLine(ls);



public static List<System.Type> FindDerivedTypes(Assembly assembly
    , System.Type typeToSearch
    ,System.Type neededInterface)
{
    List<System.Type> ls = new List<System.Type>();

    System.Type[] ta = assembly.GetTypes();

    int l = ta.Length;
    for (int i = 0; i < l; ++i)
    {
        if (ta[i].BaseType == null)
            continue;

        if (!ta[i].BaseType.IsGenericType)
            continue;

        // public class Middleman : IHttpHandler
        // public class HelloWorldHandler2 : HandlerMiddleware<Middleman>
        // public class HelloWorldHandler : HandlerMiddleware<HelloWorldHandler>, IHttpHandler

        var gt = ta[i].BaseType.GetGenericTypeDefinition();
        if (gt == null)
            continue;

        if (!object.ReferenceEquals(gt, typeToSearch))
            continue;

        Type[] typeParameters = ta[i].BaseType.GetGenericArguments();
        if (typeParameters == null || typeParameters.Length < 1)
            continue;

        if(neededInterface.IsAssignableFrom(typeParameters[0]))
            ls.Add(ta[i]);
    } // Next i 

    return ls;
} // End Function FindDerivedTypes

这就是您获得该列表的方式。

关于c# - 如何在程序集中找到所有类,这些类是通用抽象类的实例并实现某个接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47096437/

相关文章:

c# - 这真的是您使用 Linq-To-Sql 的方式吗?

asp.net - 构建一个新的 ASP.NET 应用程序 - 寻找一个好的框架

c# - 在 C# 中解析 html 的最佳方法是什么?

c# - 如何从 lambda 表达式获取值?

c# - 用于小型 .NET 项目的 IoC/DI

c# - 是否可以在 C# 方法中运行 Ajax? (MVC的 Controller )

c# - Clipboard.ContainsImage() 可靠甚至有用吗?

c# - C# 中的多维数组

c# - 我应该关注 linq 查询中的 "access to modified closure"吗?

c# - XSP 可以运行 ASP.NET 4.5 吗?