Implementations of interface through Reflection

23,072

Solution 1

The answer is this; it searches through the entire application domain -- that is, every assembly currently loaded by your application.

/// <summary>
/// Returns all types in the current AppDomain implementing the interface or inheriting the type. 
/// </summary>
public static IEnumerable<Type> TypesImplementingInterface(Type desiredType)
{
    return AppDomain
           .CurrentDomain
           .GetAssemblies()
           .SelectMany(assembly => assembly.GetTypes())
           .Where(type => desiredType.IsAssignableFrom(type));
}

It is used like this;

var disposableTypes =  TypesImplementingInterface(typeof(IDisposable));

You may also want this function to find actual concrete types -- i.e., filtering out abstracts, interfaces, and generic type definitions.

public static bool IsRealClass(Type testType)
{
    return testType.IsAbstract == false
         && testType.IsGenericTypeDefinition == false
         && testType.IsInterface == false;
}

Solution 2

Have a look at Assembly.GetTypes() method. It returns all the types that can be found in an assembly. All you have to do is to iterate through every returned type and check if it implements necessary interface.

On of the way to do so is using Type.IsAssignableFrom method.

Here is the example. myInterface is the interface, implementations of which you are searching for.

Assembly myAssembly;
Type myInterface;
foreach (Type type in myAssembly.GetTypes())
{
    if (myInterface.IsAssignableFrom(type))
        Console.WriteLine(type.FullName);
}

I do believe that it is not a very efficient way to solve your problem, but at least, it is a good place to start.

Solution 3

Assembly assembly = Assembly.GetExecutingAssembly();
List<Type> types = assembly.GetTypes();
List<Type> childTypes = new List<Type>();
foreach (Type type in Types) {
  foreach (Type interfaceType in type.GetInterfaces()) {
       if (interfaceType.Equals(typeof([yourinterfacetype)) {
            childTypes.Add(type)
            break;
       }
  }
}

Maybe something like that....

Solution 4

Here are some Type extension methods that may be useful for this, as suggested by Simon Farrow. This code is just a restructuring of the accepted answer.

Code

/// <summary>
/// Returns all types in <paramref name="assembliesToSearch"/> that directly or indirectly implement or inherit from the given type. 
/// </summary>
public static IEnumerable<Type> GetImplementors(this Type abstractType, params Assembly[] assembliesToSearch)
{
    var typesInAssemblies = assembliesToSearch.SelectMany(assembly => assembly.GetTypes());
    return typesInAssemblies.Where(abstractType.IsAssignableFrom);
}

/// <summary>
/// Returns the results of <see cref="GetImplementors"/> that match <see cref="IsInstantiable"/>.
/// </summary>
public static IEnumerable<Type> GetInstantiableImplementors(this Type abstractType, params Assembly[] assembliesToSearch)
{
    var implementors = abstractType.GetImplementors(assembliesToSearch);
    return implementors.Where(IsInstantiable);
}

/// <summary>
/// Determines whether <paramref name="type"/> is a concrete, non-open-generic type.
/// </summary>
public static bool IsInstantiable(this Type type)
{
    return !(type.IsAbstract || type.IsGenericTypeDefinition || type.IsInterface);
}

Examples

To get the instantiable implementors in the calling assembly:

var callingAssembly = Assembly.GetCallingAssembly();
var httpModules = typeof(IHttpModule).GetInstantiableImplementors(callingAssembly);

To get the implementors in the current AppDomain:

var appDomainAssemblies = AppDomain.CurrentDomain.GetAssemblies();
var httpModules = typeof(IHttpModule).GetImplementors(appDomainAssemblies);

Solution 5

Do you mean all interfaces a Type implements?

Like this:

ObjX foo = new ObjX();
Type tFoo = foo.GetType();
Type[] tFooInterfaces = tFoo.GetInterfaces();
foreach(Type tInterface in tFooInterfaces)
{
  // do something with it
}

Hope tha helpts.

Share:
23,072
Admin
Author by

Admin

Updated on June 25, 2020

Comments

  • Admin
    Admin about 4 years

    How can I get all implementations of an interface through reflection in C#?

  • Aaron
    Aaron almost 16 years
    This doesn't find types in other assemblies that implement said interface.
  • Aaron
    Aaron almost 16 years
    Note that this code can't see the future -- it can't find implementation of this interface in interfaces that have not yet been loaded.
  • user3504701
    user3504701 over 15 years
    I think that I might turn this into an extension method for Type, might turn out to be very useful.
  • David Pfeffer
    David Pfeffer about 13 years
    Steve: Can you shed any light on a similar problem I'm having: stackoverflow.com/questions/5849210/…
  • Sam
    Sam about 11 years
    You can simplify IsRealClass to return !(testType.IsAbstract || testType.IsGenericTypeDefinition || testType.IsInterface);
  • hakan
    hakan about 9 years
    .SelectMany(assembly => assembly.GetTypes()) this line gave me following exception: {"Could not load file or assembly 'Microsoft.WindowsAzure.MobileServices.Management, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f300afd708cefcd3' or one of its dependencies. The system cannot find the file specified.":"Microsoft.WindowsAzure.MobileServices.Managemen‌​t, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f300afd708cefcd3"}
  • Steve Cooper
    Steve Cooper about 9 years
    @piedpiper - my guess is that (a) your project references that file, (b) In the project properties, it's been marked 'copy local=false', and maybe (c) no code references anything in it. So your code compiles, but when reflection comes to load the type, it can't find the assembly in question and craps out. I'd suggest removing the reference if it's not used. Hope that's some help...