Как получить все экземпляры всех загруженных типов, реализующих данный интерфейс?

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

Ответы

Ответ 1

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

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

Ответ 2

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

Здесь некоторый псевдокод, который выглядит замечательно как С# и может даже компилировать и возвращать то, что вам нужно. Если ничего другого, он укажет вам в правильном направлении:

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(может быть вычислена с помощью отладчиков/профилировщиков путем изучения кучи/стека).

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

Ответ 3

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

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

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

  • Загрузите сборку
  • Итерации через него (вызов asm.GetTypes())
  • Проверить тип (IMyInterface).IsAssignibleFrom(testType)

Ответ 4

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

Ответ 5

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[] {};
}