.net 如何反射取得所有的类型, 或者某些子类.
方式一
/// <summary>
/// 反射取得所有的业务逻辑类
/// </summary>
private static Type[] GetAllChildClass( Type baseType)
{
var types = AppDomain.CurrentDomain.GetAssemblies()
//取得实现了某个接口的类
//.SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(ISecurity)))) .ToArray();
//取得继承了某个类的所有子类
.SelectMany(a => a.GetTypes().Where(t => t.BaseType == baseType))
.ToArray();
return types;
}
方式二
public List<Type> GetAllChildClass( Type baseType)
{
string Location = baseType.Assembly.Location;
var path = System.IO.Path.GetDirectoryName(Location);
var files = System.IO.Directory.GetFiles(path,"*.dll");
//var baseType = typeof(AbstractBLogic);
List<Type> blogics = new List<Type>();
foreach (var file in files)
{
var types = Assembly.LoadFile(file).GetTypes();
foreach (var t in types)
{
var tmp = t.BaseType;
while (tmp != null)
{
if (tmp == baseType)
{
//AbstractBLogic obj = Activator.CreateInstance(t) as AbstractBLogic;
//if (obj != null)
//{
// blogics.Add(obj);
//}
blogics.Add(t);
break;
}
else
{
tmp = tmp.BaseType;
}
}
}
}
return blogics;
}
在这里我推荐使用方式一, 因为方式一里面不会存在dll释放的问题.
方式二 在Assembly.LoadFile(file)的时候会把dll加载到内存, 并且还无法释放.运行多了容易慢.
想要释放dll不是不可以, 需要新建一个AppDomain 然后再加载dll文件. 很麻烦, 如果一定需要动态加载某个文件夹下面的dll , 那么方式二是一个备用选择, 不过代码要稍微改一下.
尤其是在asp.net 这种自动加载dll的场景下. 建议使用方式一.