it-swarm-pt.tech

Implementações de interface através do Reflection

Como posso obter todas as implementações de uma interface por meio de reflexão em C #?

39
Chethan

Dê uma olhada no método Assembly.GetTypes(). Ele retorna todos os tipos que podem ser encontrados em uma Assembléia. Tudo que você precisa fazer é iterar por meio de cada tipo retornado e verificar se ele implementa a interface necessária.

A caminho de fazer isso está usando Type.IsAssignableFrom método.

Aqui está o exemplo. myInterface é a interface cujas implementações você está procurando.

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

Eu acredito que não é uma maneira muito eficiente de resolver seu problema, mas pelo menos, é um bom lugar para começar.

5
Anton
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;
       }
  }
}

Talvez algo assim ....

4
Adam Driscoll

Aqui estão alguns métodos de extensão Type que podem ser úteis para isso, conforme sugerido por Simon Farrow . Este código é apenas uma reestruturação da resposta aceita.

Código

/// <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);
}

Exemplos

Para obter os implementadores instanciados no Assembly de chamada:

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

Para obter os implementadores no AppDomain atual:

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

Você deve fazer um loop em todos os assemblies nos quais está interessado. No Assembly, você pode obter todos os tipos que ele define. Observe que quando você faz AppDomain.CurrentDomain.Assemblies, você obtém apenas os assemblies que são carregados. Os assemblies não são carregados até que sejam necessários, o que significa que você deve carregar os assemblies explicitamente antes de iniciar a pesquisa.

1
Hallgrim

Você quer dizer todas as interfaces que um tipo implementa?

Como isso:

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

Espero que ajude.

1
Alex Duggleby