C# 如何查找程序集中属于泛型抽象类实例的所有类并实现特定接口
如何在程序集中找到作为泛型抽象类实例的所有类并实现某个接口 注:C# 如何查找程序集中属于泛型抽象类实例的所有类并实现特定接口,c#,asp.net,.net,asp.net-core,.net-core,C#,Asp.net,.net,Asp.net Core,.net Core,如何在程序集中找到作为泛型抽象类实例的所有类并实现某个接口 注: 该接口也可以在从实现该接口的另一个类继承的类中实现 一个具体的例子: 我有下面的接口和中间件类: public interface IHttpHandler { bool IsReusable { get; } void ProcessRequest(HttpContext context); } public abstract class HandlerMiddleware<T> where T:
该接口也可以在从实现该接口的另一个类继承的类中实现 一个具体的例子:
我有下面的接口和中间件类:
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
公共接口IHttpHandler
{
布尔可重用{get;}
void ProcessRequest(HttpContext上下文);
}
公共抽象类handler中间件,其中T:IHttpHandler
{
private readonly RequestDelegate\u next;
公共HandlerMiddleware()
{ }
公共HandlerMiddleware(RequestDelegate下一步)
{
_下一个=下一个;
}
公共异步任务调用(HttpContext上下文)
{
等待同步调用(上下文);
}
公共任务SyncInvoke(HttpContext上下文)
{
//IHttpHandler handler=(IHttpHandler)this;
T handler=System.Activator.CreateInstance();
ProcessRequest(上下文);
返回Task.CompletedTask;
}
}//结束抽象类handler中间件
如何找到所有实现抽象类和IHttpHandler的类,如HelloWorldHandler
请注意,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(“/hello”)]
公共类HelloWorldHandler
:handler,IHttpHandler
{
公共HelloWorldHandler():base(){}
公共HelloWorldHandler(RequestDelegate下一个):基(下一个){}
void IHttpHandler.ProcessRequest(HttpContext上下文)
{
context.Response.ContentType=“text/plain”;
//wait context.Response.WriteAsync(“Hello World!”);
byte[]buffer=System.Text.Encoding.UTF8.GetBytes(“hello world”);
context.Response.Body.Write(buffer,0,buffer.Length);
}
布尔·伊赫特芬德勒是可维修的
{
得到
{
返回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();
}
}
[HandlerPath(“/hello2”)]
公共类HelloWorldHandler2
:handler中间件
{
公共HelloWorldHandler2():base(){}
公共HelloWorldHandler2(RequestDelegate下一个):基(下一个){}
}
公营中间人
:IHttpHandler
{
bool IHttpHandler.IsReusable=>抛出新的NotImplementedException();
void IHttpHandler.ProcessRequest(HttpContext上下文)
{
抛出新的NotImplementedException();
}
}
这将为您提供在当前域的程序集中实现IHttpHandler的所有类:
List<Type> result = new List<Type>();
var assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
foreach(var assem in assemblies)
{
var list = assem.GetExportedTypes().Where(t => t.GetInterfaces().Contains(typeof(IHttpHandler))).ToList();
if (list != null && list.Count != 0)
{
result.AddRange(list);
}
}
见:
用法:IsSubclassOfRawGeneric(typeof(HandlerMiddleware),typeToCheck)您的问题实际上相当复杂,难以理解
问题是您的类是从泛型类派生的,其泛型参数实现了IHttpHandler 您需要获取继承的(基)类型(因为您是从它继承的)
这是泛型类型,所以需要检查它是否是泛型类型
如果是es,则需要获取泛型类型(GetGenericTypeDefinition)。
然后需要检查泛型类型是否为HandlerMiddleware类型
然后需要从泛型类型中获取参数
然后需要检查第一个泛型参数(如果有)。
然后,您需要检查泛型参数的类型(或其派生基)是否实现了所讨论的接口 因此,在你的情况下:
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
var ls=FindDerivedTypes(t.Assembly,typeof(handler中间件),typeof(IHttpHandler));
系统控制台写入线(ls);
公共静态列表查找驱动类型(程序集
,System.Type typeToSearch
,System.Type需要接口)
{
列表ls=新列表();
System.Type[]ta=assembly.GetTypes();
int l=ta.长度;
对于(int i=0;i
这就是你得到这份名单的原因 实现了IHttpHandler的所有结构类HandlerMiddleware(不管实现本身是否抛出未实现)。这个“查找”的上下文是什么?您是在寻找有关如何使用Visual Studio的建议,还是希望编写在运行时执行此搜索的反射代码?@Damien_The_unsiever:问得好。我的意思是在运行时搜索。只需使用
typeof(HandlerMiddleware).IsAssignableFrom(type)和&typeof(IHttpHandler).IsAssignableFrom(type)
。扩展到typeof(在汇编中键入).assembly.GetTypes().Where(t=>typeof(HandlerMiddleware).IsAssignableFrom(t)和&typeof(IHttpHandler.IsAssignableFrom(type)).ToArray()代码>可能重复的否,您不能,因为IsSubclassOf类型是泛型类型。确定,为泛型类型添加了另一段代码
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