Как найти все классы, которые реализуют данный интерфейс?
под заданным пространством имен у меня есть набор классов, которые реализуют интерфейс. Давайте назовем это ISomething
. У меня есть еще один класс (назовем его CClass
), который знает о ISomething
но не знает о классах, которые реализуют этот интерфейс.
Я бы вот так CClass
искать все реализации ISomething
, создайте его экземпляр и выполните метод.
кто-нибудь имеет представление о том, как это сделать с C# 3.5?
6 ответов:
рабочий код-пример:
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 }
Edit добавлена проверка для конструктора без параметров, так что вызов CreateInstance будет успешным.
вы можете получить список загруженных сборок с помощью этого:
Assembly assembly = System.Reflection.AppDomain.CurrentDomain.GetAssemblies()
оттуда, вы можете получить список типов в сборке (при условии открытых типов):
Type[] types = assembly.GetExportedTypes();
затем вы можете спросить каждый тип, поддерживает ли он этот интерфейс, найдя этот интерфейс на объекте:
Type interfaceType = type.GetInterface("ISomething");
не уверен, если есть более эффективный способ сделать это с отражением.
пример использования Linq:
var types = myAssembly.GetTypes() .Where(m => m.IsClass && m.GetInterface("IMyInterface") != null);
foreach (Type t in Assembly.GetCallingAssembly().GetTypes()) { if (t.GetInterface("ITheInterface") != null) { ITheInterface executor = Activator.CreateInstance(t) as ITheInterface; executor.PerformSomething(); } }
вы могли бы использовать что-то вроде следующего и адаптировать его к вашим потребностям.
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(); } }
этот код может использовать некоторые улучшения производительности, но это только начало.