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