2010-07-21 14 views
6

He creado un atributo personalizado para decorar un número de clases que quiero para consultar en tiempo de ejecución:atributo de herencia y Reflexión

[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=true)] 
public class ExampleAttribute : Attribute 
{ 
    public ExampleAttribute(string name) 
    { 
     this.Name = name; 
    } 

    public string Name 
    { 
     get; 
     private set; 
    } 
} 

Cada una de estas clases se derivan de una clase base abstracta:

[Example("BaseExample")] 
public abstract class ExampleContentControl : UserControl 
{ 
    // class contents here 
} 

public class DerivedControl : ExampleContentControl 
{ 
    // class contents here 
} 

¿Debo colocar este atributo en cada clase derivada, incluso si lo agrego a la clase base? El atributo se marca como heredable, pero cuando hago la consulta, solo veo la clase base y no las clases derivadas.

De another thread:

var typesWithMyAttribute = 
    from a in AppDomain.CurrentDomain.GetAssemblies() 
    from t in a.GetTypes() 
    let attributes = t.GetCustomAttributes(typeof(ExampleAttribute), true) 
    where attributes != null && attributes.Length > 0 
    select new { Type = t, Attributes = attributes.Cast<ExampleAttribute>() }; 

, gracias, WTS

Respuesta

3

que corrían el código tal como está, y obtuvo el siguiente resultado:

{ Type = ConsoleApplication2.ExampleContentControl, Attributes = ConsoleApplication2.ExampleAttribute[] } 
{ Type = ConsoleApplication2.DerivedControl, Attributes = ConsoleApplication2.ExampleAttribute[] } 

Por lo tanto, parece que funciona ... ¿Estás seguro de que algo más no está sucediendo?

+0

Intenta poner una clase derivada en otro proyecto, haciendo referencia al primero. Si pongo la clase derivada en el mismo espacio de nombres que la base, funciona. –

+0

Bueno, la mitad lo descubrió: los otros ensamblajes aún no estaban cargados cuando se llamó a la consulta LINQ. Supongo que la pregunta es: "¿cómo obtengo todos los ensamblajes que están asociados con mi ejecutable (es decir, con qué reemplazo la llamada de AppDomain.CurrentDomain.GetAssemblies()?" –

+0

Correcto, eso tiene sentido ... debe encontrar la manera de forzar una carga en todos los ensambles que puedan importar. Esto realmente depende de cómo está estructurada tu aplicación. Si, por ejemplo, todos los ensamblajes se cargan desde la carpeta donde se ejecuta la aplicación, puede escanear y forzar una carga. Si estás haciendo algo exótico, como redirigir cargas de montaje ... es más complicado. Si sabe con anticipación qué ensamblajes espera encontrar allí, lo más simple es hacer referencia a algún tipo dentro de cada uno de esos ensamblajes. –