2008-11-19 18 views

Respuesta

6

No creo que haya una manera ... Tendría que ser capaz de recorrer el Heap, examinar cada objeto allí, o recorrer la pila de cada hilo activo en el espacio de proceso de la aplicación, examinando cada variable de referencia de pila en cada subproceso ...

La otra forma (supongo que no se puede) es interceptar todas las actividades de creación de objetos (utilizando un enfoque de contenedor) y mantener una lista de todos los objetos en su aplicación. ..

17

Si necesita instancias (ejemplos) de todos los tipos que implementan una interfaz particular, puede examinar todos los tipos, buscar la interfaz y crear una instancia si se encuentra una coincidencia.

Aquí hay un pseudocódigo que se parece notablemente a C# e incluso puede compilar y devolver lo que necesita. Si nada más, que te orientará en la dirección correcta:

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

Ahora, si estamos hablando acerca de caminar la pila y volviendo casos anteriormente ejemplificados de todos los objetos que implementan un tipo particular, la buena suerte de que a medida esta información no es almacenada por .Net runtime (puede ser calculada por debugers/profilers al examinar heap/stack).

Dependiendo de la razón por la que cree que debe hacer eso, probablemente haya mejores formas de hacerlo.

+1

Sí, quiero obtener instancias previamente instanciadas. Es porque cargamos módulos que almacenan su configuración utilizando objetos que implementan la misma interfaz, pero no parece haber otra manera de sacar las instancias de configuración. – Simon

+0

+1 gracias. Agregué el elenco a T, lo que hizo que el código compilara para mí. –

+0

@SamHolder: Oye, puedes editar para corregir cualquier error que encuentres ... – Will

4

Todas las instancias de un objeto, o todos los tipos?

Obtener todas las instancias de un objeto sería casi imposible, e involucraría información no pública sobre el escaneo a través de la memoria de administración.

Obtener todos los tipos que implementan una interfaz dada es factible --- dentro de un dominio dado. (Es decir, se puede encontrar todo tipo definido dentro de un conjunto que implementan una interfaz en particular)

  • Cargar la Asamblea
  • Iterar a través de él de tipos (llamar asm.GetTypes())
  • Comprobar typeof (IMyInterface) .IsAssignibleFrom (testType)
+0

Todas las instancias de un objeto. – Simon

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[] {}; 
} 
+0

nice - pero ¿cómo obtengo las instancias de esos tipos? – Simon

+0

@Simon, la única manera de hacerlo es registrar referencias a cada instancia en la creación. No puede acceder a ellos sin establecer dicho mecanismo por adelantado. Dependiendo de su caso de uso, es posible que desee consultar [ObservableCollection] (http://msdn.microsoft.com/en-us/library/ms668604.aspx) ... ¿Cuál es su caso de uso? – smartcaveman

+0

es según mi comentario en la respuesta de @Will: cargamos módulos que almacenan su configuración utilizando objetos que implementan la misma interfaz, pero no parece haber otra forma de sacar las instancias de configuración. – Simon

2

Si las clases que implementan la interfaz especificada son los suyos a continuación, puede aplicar una lista de referencias débiles durante la instanciación.

+0

Me temo que no son todas nuestras. – Simon

Cuestiones relacionadas