如何在程序集中找到作为通用抽象类实例并实现特定接口(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/