Using reflection, how can I get all types that implement an interface with C# 3.0/.NET 3.5 with the least code, and minimizing iterations?
This is what I want to re-
You could use some LINQ to get the list:
var types = from type in this.GetType().Assembly.GetTypes()
where type is ISomeInterface
select type;
But really, is that more readable?
This worked for me (if you wish you could exclude system types in the lookup):
Type lookupType = typeof (IMenuItem);
IEnumerable<Type> lookupTypes = GetType().Assembly.GetTypes().Where(
t => lookupType.IsAssignableFrom(t) && !t.IsInterface);
loop through all loaded assemblies, loop through all their types, and check if they implement the interface.
something like:
Type ti = typeof(IYourInterface);
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) {
foreach (Type t in asm.GetTypes()) {
if (ti.IsAssignableFrom(t)) {
// here's your type in t
}
}
}
Mine would be this in c# 3.0 :)
var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
Basically, the least amount of iterations will always be:
loop assemblies
loop types
see if implemented.
There's no easy way (in terms of performance) to do what you want to do.
Reflection works with assemblys and types mainly so you'll have to get all the types of the assembly and query them for the right interface. Here's an example:
Assembly asm = Assembly.Load("MyAssembly");
Type[] types = asm.GetTypes();
Type[] result = types.where(x => x.GetInterface("IMyInterface") != null);
That will get you all the types that implement the IMyInterface in the Assembly MyAssembly
Other answer were not working with a generic interface.
This one does, just replace typeof(ISomeInterface) by typeof (T).
List<string> types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes())
.Where(x => typeof(ISomeInterface).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract)
.Select(x => x.Name).ToList();
So with
AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes())
we get all the assemblies
!x.IsInterface && !x.IsAbstract
is used to exclude the interface and abstract ones and
.Select(x => x.Name).ToList();
to have them in a list.