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

时间:2022-09-25 11:59:03

Under a given namespace, I have a set of classes which implement an interface. Let's call it ISomething. I have another class (let's call it CClass) which knows about ISomething but doesn't know about the classes which implement that interface.

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

I would like that CClass to look for all the implementation of ISomething, instantiate an instance of it and execute the method.

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

Does anybody have an idea on how to do that with C# 3.5?

有没有人知道如何用C#3.5做到这一点?

6 个解决方案

#1


A working code-sample:

一个有效的代码示例:

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 Added a check for a parameterless constructor so that the call to CreateInstance will succeed.

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

#2


You can get a list of loaded assemblies by using this:

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

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

From there, you can get a list of types in the assembly (assuming public types):

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

Type[] types = assembly.GetExportedTypes();

Then you can ask each type whether it supports that interface by finding that interface on the object:

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

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

Not sure if there is a more efficient way of doing this with reflection.

不确定是否有更有效的方法来做反射。

#3


A example using Linq:

使用Linq的一个例子:

var types =
  myAssembly.GetTypes()
            .Where(m => m.IsClass && m.GetInterface("IMyInterface") != null);

#4


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

#5


You could use something like the following and tailor it to your needs.

您可以使用以下内容并根据您的需要进行定制。

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

This code could use some performance enhancements but it's a start.

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

#6


Maybe we should go this way

也许我们应该这样做

foreach ( var instance in Assembly.GetExecutingAssembly().GetTypes().Where(a => a.GetConstructor(Type.EmptyTypes) != null).Select(Activator.CreateInstance).OfType<ISomething>() ) 
   instance.Execute(); 

#1


A working code-sample:

一个有效的代码示例:

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 Added a check for a parameterless constructor so that the call to CreateInstance will succeed.

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

#2


You can get a list of loaded assemblies by using this:

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

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

From there, you can get a list of types in the assembly (assuming public types):

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

Type[] types = assembly.GetExportedTypes();

Then you can ask each type whether it supports that interface by finding that interface on the object:

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

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

Not sure if there is a more efficient way of doing this with reflection.

不确定是否有更有效的方法来做反射。

#3


A example using Linq:

使用Linq的一个例子:

var types =
  myAssembly.GetTypes()
            .Where(m => m.IsClass && m.GetInterface("IMyInterface") != null);

#4


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

#5


You could use something like the following and tailor it to your needs.

您可以使用以下内容并根据您的需要进行定制。

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

This code could use some performance enhancements but it's a start.

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

#6


Maybe we should go this way

也许我们应该这样做

foreach ( var instance in Assembly.GetExecutingAssembly().GetTypes().Where(a => a.GetConstructor(Type.EmptyTypes) != null).Select(Activator.CreateInstance).OfType<ISomething>() ) 
   instance.Execute();