We need to get all the instances of objects that implement a given interface - can we do that, and if so how?
我们需要获得实现给定接口的所有对象实例 - 我们可以这样做,如果是这样,如何?
5 个解决方案
#1
6
I don't believe there is a way... You would have to either be able to walk the Heap, and examine every object there, or walk the stack of every active thread in the application process space, examining every stack reference variable on every thread...
我不相信有一种方法......你必须要么能够遍历堆,并检查那里的每个对象,或者在应用程序进程空间中遍历每个活动线程的堆栈,检查每个堆栈引用变量每一个线程......
The other way, (I am guessing you can't do) is intercept all Object creation activities (using a container approach) and keep a list of all objects in your application...
另一种方式,(我猜你做不到)是拦截所有对象创建活动(使用容器方法)并保留应用程序中所有对象的列表...
#2
17
If you need instances (samples) of all types implementing particular interface you can go through all types, check for interface and create instance if match found.
如果您需要实现特定接口的所有类型的实例(示例),您可以浏览所有类型,检查接口并在找到匹配时创建实例。
Here's some pseudocode that looks remarkably like C# and may even compile and return what you need. If nothing else, it will point you in the correct direction:
这里有一些看起来非常像C#的伪代码,甚至可以编译并返回你需要的东西。如果没有别的,它会指出你正确的方向:
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;
}
}
}
}
Now, if you're talking about walking the heap and returning previously instantiated instances of all objects that implement a particular type, good luck on that as this information is not stored by .Net runtime (can be computed by debugers/profilers by examining heap/stack so).
现在,如果您正在谈论遍历堆并返回实现特定类型的所有对象的先前实例化实例,那么好运就是因为.Net运行时不存储此信息(可以通过检查堆来计算debugers / profilers / stack so)。
Depending on the reason why you think you need to do that there are probably better ways of going about it.
根据您认为需要这样做的原因,可能有更好的方法来实现它。
#3
4
All instances of an Object, or all Types?
对象的所有实例,还是所有类型?
Getting all instances of an Object would be pretty close to impossible, and would involve non-public information about the scan through management memory.
获取对象的所有实例几乎是不可能的,并且涉及有关扫描管理内存的非公开信息。
Getting all types that implement a given interface is doable --- within a given domain. (ie, you can find all type defined within an assembly that implement a particular interface)
获取实现给定接口的所有类型都是可行的---在给定的域内。 (即,您可以找到实现特定接口的程序集中定义的所有类型)
- Load the Assembly
- Iterate through it's types (call asm.GetTypes())
- Check typeof(IMyInterface).IsAssignibleFrom(testType)
加载程序集
迭代它的类型(调用asm.GetTypes())
#4
2
If the classes implementing the specified interface are yours then you can implement a list of weak references upon instantiation.
如果实现指定接口的类是您的,那么您可以在实例化时实现弱引用列表。
#5
1
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[] {};
}
#1
6
I don't believe there is a way... You would have to either be able to walk the Heap, and examine every object there, or walk the stack of every active thread in the application process space, examining every stack reference variable on every thread...
我不相信有一种方法......你必须要么能够遍历堆,并检查那里的每个对象,或者在应用程序进程空间中遍历每个活动线程的堆栈,检查每个堆栈引用变量每一个线程......
The other way, (I am guessing you can't do) is intercept all Object creation activities (using a container approach) and keep a list of all objects in your application...
另一种方式,(我猜你做不到)是拦截所有对象创建活动(使用容器方法)并保留应用程序中所有对象的列表...
#2
17
If you need instances (samples) of all types implementing particular interface you can go through all types, check for interface and create instance if match found.
如果您需要实现特定接口的所有类型的实例(示例),您可以浏览所有类型,检查接口并在找到匹配时创建实例。
Here's some pseudocode that looks remarkably like C# and may even compile and return what you need. If nothing else, it will point you in the correct direction:
这里有一些看起来非常像C#的伪代码,甚至可以编译并返回你需要的东西。如果没有别的,它会指出你正确的方向:
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;
}
}
}
}
Now, if you're talking about walking the heap and returning previously instantiated instances of all objects that implement a particular type, good luck on that as this information is not stored by .Net runtime (can be computed by debugers/profilers by examining heap/stack so).
现在,如果您正在谈论遍历堆并返回实现特定类型的所有对象的先前实例化实例,那么好运就是因为.Net运行时不存储此信息(可以通过检查堆来计算debugers / profilers / stack so)。
Depending on the reason why you think you need to do that there are probably better ways of going about it.
根据您认为需要这样做的原因,可能有更好的方法来实现它。
#3
4
All instances of an Object, or all Types?
对象的所有实例,还是所有类型?
Getting all instances of an Object would be pretty close to impossible, and would involve non-public information about the scan through management memory.
获取对象的所有实例几乎是不可能的,并且涉及有关扫描管理内存的非公开信息。
Getting all types that implement a given interface is doable --- within a given domain. (ie, you can find all type defined within an assembly that implement a particular interface)
获取实现给定接口的所有类型都是可行的---在给定的域内。 (即,您可以找到实现特定接口的程序集中定义的所有类型)
- Load the Assembly
- Iterate through it's types (call asm.GetTypes())
- Check typeof(IMyInterface).IsAssignibleFrom(testType)
加载程序集
迭代它的类型(调用asm.GetTypes())
#4
2
If the classes implementing the specified interface are yours then you can implement a list of weak references upon instantiation.
如果实现指定接口的类是您的,那么您可以在实例化时实现弱引用列表。
#5
1
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[] {};
}