Как мне получить все экземпляры всех загруженных типов, которые реализуют данный интерфейс? - PullRequest
16 голосов
/ 19 ноября 2008

Нам нужно получить все экземпляры объектов, которые реализуют данный интерфейс - можем ли мы это сделать, и если да, то как?

Ответы [ 5 ]

17 голосов
/ 19 ноября 2008

Если вам нужны экземпляры (образцы) всех типов, реализующих определенный интерфейс, вы можете пройти через все типы, проверить интерфейс и создать экземпляр, если совпадение найдено.

Вот некоторый псевдокод, который замечательно похож на C # и может даже скомпилировать и вернуть то, что вам нужно. Если ничего другого, он укажет вам правильное направление:

public static IEnumerable<T> GetInstancesOfImplementingTypes<T>()
{
    AppDomain app = AppDomain.CurrentDomain;
    Assembly[] ass = app.GetAssemblies();
    Type[] types;
    Type targetType = typeof(T);

    foreach (Assembly a in ass)
    {
        types = a.GetTypes();
        foreach (Type t in types)
        {
            if (t.IsInterface) continue;
            if (t.IsAbstract) continue;
            foreach (Type iface in t.GetInterfaces())
            {
                if (!iface.Equals(targetType)) continue;
                yield return (T) Activator.CreateInstance(t);
                break;
            }
        }
    }
}

Теперь, если вы говорите об обходе кучи и возврате ранее созданных экземпляров всех объектов, которые реализуют определенный тип, удачи вам, так как эта информация не сохраняется в среде выполнения .Net (может быть вычислена отладчиками / профилировщиками исследуя кучу / стек так).

В зависимости от причины, по которой вы считаете, что вам нужно это сделать, возможно, есть лучшие способы сделать это.

7 голосов
/ 19 ноября 2008

Я не верю, что есть способ ... Вам нужно будет либо пройтись по куче и исследовать каждый объект, либо пройтись по стеку каждого активного потока в пространстве процессов приложения, изучая каждый стек ссылочная переменная в каждом потоке ...

Другой способ (я полагаю, вы не можете этого сделать) - перехватывать все действия по созданию объектов (используя контейнерный подход) и хранить список всех объектов в вашем приложении ...

4 голосов
/ 19 ноября 2008

Все экземпляры объекта или все типы?

Получение всех экземпляров объекта было бы практически невозможно, и в нем содержалась бы непубличная информация о сканировании через память управления.

Получение всех типов, которые реализуют данный интерфейс, выполнимо --- в пределах данного домена. (то есть вы можете найти все типы, определенные в сборке, которые реализуют определенный интерфейс)

  • Загрузить сборку
  • Перебирать его типы (вызывать asm.GetTypes ())
  • Проверка typeof (IMyInterface) .IsAssignibleFrom (testType)
2 голосов
/ 06 февраля 2012

Если классы, реализующие указанный интерфейс, принадлежат вам, вы можете реализовать список слабых ссылок после создания экземпляра.

1 голос
/ 07 июня 2011
IEnumerable<Type> GetAllTypesThatImplementInterface<T>()
{
    var @interface = typeof (T);
    return @interface.IsInterface
               ? AppDomain.CurrentDomain.GetAssemblies()
                     .SelectMany(assembly => assembly.GetTypes())
                     .Where(type => !type.IsInterface
                                 && !type.IsAbstract 
                                 && type.GetInterfaces().Contains(@interface))
               : new Type[] {};
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...