Reputation: 18186
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.
Upvotes: 21
Views: 36184
Reputation: 2094
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.
Upvotes: 32
Reputation: 39916
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.
Upvotes: 9
Reputation: 42928
That's because your type
variable is a Type
, not a CommandBase
.
You want
if(type == typeof(CommandBase))
(Thanks Greg for the correction)
Upvotes: 2
Reputation: 10280
Change type is CommandBase
to typeof(CommandBase).IsAssignableFrom(type)
Upvotes: 8