Как получить все экземпляры всех загруженных типов, реализующих данный интерфейс?
Нам нужно получить все экземпляры объектов, реализующих данный интерфейс, - можем ли мы это сделать, и если да, то как?
Ответы
Ответ 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[] {};
}