Using reflection to get all classes of certain base type in dll
I have a dll that contains a number of classes that all inherit from a CommandBase class. I'm trying to get instances of all of these classes (CommandA, CommandB, CommandC, etc...) using reflection in C# so that I can call a specific method on each one. Here is what I have so far:
//get assemblies in directory.
string folder = Path.Combine(HttpContext.Current.Server.MapPath("~/"), "bin");
var files = Directory.GetFiles(folder, "*.dll");
//load each assembly.
foreach (string file in files)
{
var assembly = Assembly.LoadFile(file);
if (assembly.FullName == "MyCommandProject")
{
foreach (var type in assembly.GetTypes())
{
if (!type.IsClass || type.IsNotPublic) continue;
if(type is CommandBase)
{
var command = Activator.CreateInstance(type) as CommandBase;
}
}
}
}
I'm having 2 issues. The 1st issue is that the line "if(type is CommandBase") gives the following warning:
The given expression is never of the provided type CommandBase.
The 2nd issue开发者_如何学运维 is that I can't figure out how to get an instance of the actual object (CommandA, CommandB, etc...), just converting it to CommandBase isn't enough.
This is the method I use to load up based on an interface.
private static List<T> GetInstances<T>()
{
return (from t in Assembly.GetExecutingAssembly().GetTypes()
where t.GetInterfaces().Contains(typeof (T)) && t.GetConstructor(Type.EmptyTypes) != null
select (T) Activator.CreateInstance(t)).ToList();
}
And here's the same function that pulls back based on base class.
private static IList<T> GetInstances<T>()
{
return (from t in Assembly.GetExecutingAssembly().GetTypes()
where t.BaseType == (typeof(T)) && t.GetConstructor(Type.EmptyTypes) != null
select (T)Activator.CreateInstance(t)).ToList();
}
Of course it would need to be modified slightly to point at the reference you're loading.
You must change
if(type is CommandBase)
to
if(type.IsSubclassOf(typeof(CommandBase)))
If the IsSubclassOf is the converse of IsAssignableFrom. That is, if t1.IsSubclassOf(t2) is true, then t2.IsAssignableFrom(t1) is also true.
Change type is CommandBase
to typeof(CommandBase).IsAssignableFrom(type)
That's because your type
variable is a Type
, not a CommandBase
.
You want
if(type == typeof(CommandBase))
(Thanks Greg for the correction)
精彩评论