如何找到实现给定接口的所有类?


69

在给定的名称空间下,我有一组实现接口的类。叫它ISomething。我有另一个类(我们称之为CClass),它知道ISomething但不知道实现该接口的类。

我希望CClass查找的所有实现ISomething,实例化它的一个实例并执行该方法。

有人对使用C#3.5做到这一点有想法吗?


Answers:


133

工作代码示例:

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
}

编辑添加了对无参数构造函数的检查,以便对CreateInstance的调用将成功。


9
微小的清理建议-使用Type.EmptyTypes而不是实例化新的空Type数组。
达斯汀·坎贝尔

有没有办法在所有已加载的程序集中执行此操作?
gregmac,

13
没关系.. var实例=来自AppDomain.CurrentDomain.GetAssemblies(),来自于Assembly.GetTypes()中的t,其中t.GetInterfaces()。Contains(typeof(ISomething))&& t.GetConstructor(Type.EmptyTypes)!= null选择Activator.CreateInstance(t)作为ISomething;
gregmac

真好!自从我开始使用MEF以来,我不必尝试这种方法。:)
马特·汉密尔顿,

+1:我有一个仅使用老式反射的代码片段,但这要好得多。
Brian MacKay 2010年

10

您可以使用以下方法获取已加载程序集的列表:

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

从那里,您可以获取程序集中的类型列表(假设使用公共类型):

Type[] types = assembly.GetExportedTypes();

然后,可以通过在对象上找到该接口来询问每种类型是否支持该接口:

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

不知道是否有一种更有效的反射方式。



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

2

您可以使用以下内容,并根据需要进行调整。

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();
    }
}

该代码可以使用一些性能增强功能,但这只是一个开始。


0

也许我们应该走这条路

foreach ( var instance in Assembly.GetExecutingAssembly().GetTypes().Where(a => a.GetConstructor(Type.EmptyTypes) != null).Select(Activator.CreateInstance).OfType<ISomething>() ) 
   instance.Execute(); 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.