66 votes

Comment trouver toutes les classes qui implémentent une interface donnée ?

Sous un espace de nom donné, j'ai un ensemble de classes qui implémentent une interface. Appelons-la ISomething . J'ai une autre classe (appelons-la CClass ) qui connaît ISomething mais ne connaît pas les classes qui implémentent cette interface.

Je voudrais que CClass pour rechercher toutes les mises en œuvre de ISomething , instanciez une instance de celui-ci et exécutez la méthode.

Quelqu'un a-t-il une idée sur la façon de faire cela avec C# 3.5 ?

Merci !

130voto

Matt Hamilton Points 98268

Un échantillon de code fonctionnel :

var instances = from t in Assembly.GetExecutingAssembly().GetTypes()
                where t.GetInterfaces().Contains(typeof(ISomething))
                         && t.GetConstructor(Type.EmptyTypes) != null
                select Activator.CreateInstance(t) as ISomething;

foreach (var instance in instances)
{
    instance.Foo(); // where Foo is a method of ISomething
}

Modifier Ajout d'une vérification pour un constructeur sans paramètre afin que l'appel à CreateInstance réussisse.

10voto

Mitch Denny Points 1177

Vous pouvez obtenir une liste des assemblages chargés en utilisant ceci :

Assembly assembly = System.Reflection.AppDomain.CurrentDomain.GetAssemblies()

De là, vous pouvez obtenir une liste des types dans l'assemblage (en supposant que les types publics) :

Type[] types = assembly.GetExportedTypes();

Ensuite, vous pouvez demander à chaque type s'il supporte cette interface en trouvant cette interface sur l'objet :

Type interfaceType = type.GetInterface("ISomething");

Je ne suis pas sûr qu'il existe un moyen plus efficace de faire cela avec la réflexion.

8voto

CMS Points 315406

Un exemple utilisant Linq :

var types =
  myAssembly.GetTypes()
            .Where(m => m.IsClass && m.GetInterface("IMyInterface") != null);

3voto

Kiran Points 21
foreach (Type t in Assembly.GetCallingAssembly().GetTypes())
{
    if (t.GetInterface("ITheInterface") != null)
    {
        ITheInterface executor = Activator.CreateInstance(t) as ITheInterface;
        executor.PerformSomething();
    }
}

2voto

Quintin Robinson Points 41988

Vous pourriez utiliser quelque chose comme ce qui suit et l'adapter à vos besoins.

var _interfaceType = typeof(ISomething);
var currentAssembly = System.Reflection.Assembly.GetExecutingAssembly();
var types = GetType().GetNestedTypes();

foreach (var type in types)
{
    if (_interfaceType.IsAssignableFrom(type) && type.IsPublic && !type.IsInterface)
    {
        ISomething something = (ISomething)currentAssembly.CreateInstance(type.FullName, false);
        something.TheMethod();
    }
}

Ce code pourrait être amélioré sur le plan des performances, mais c'est un début.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X