none
Assembly and Attributes RRS feed

  • Pregunta

  • Buenas tardes:
    Tengo un problema, que no consigo resolver:
    Estoy tratando de leer los atributos mediante reflexion, consigo leer los atributos pero no puedo hacer un conver al tipo de atributo, para poder acceder a las propiedades que lleva el atributo.
    Mi codigo es el siguiente:

    object[] atributosPropios = tipoTipo.GetCustomAttributes(tipo1 , false);
     foreach (System.Attribute atributo in atributosPropios)
                {
                    string sNombre=((NombreTablaAttribute)atributo).nombreTabla;
                }


    el problema lo tengo que NombreTablaAttribute es el tipo de atributo, pero tengo que obtener ese tipo tambien por reflexion, ya que este ejecutable es el de actualizacion y debe ser independiente de todas las librerias del proyecto, y vamos a acceder a dicha informacion por reflexion.


    Muchas gracias
    martes, 11 de diciembre de 2007 12:30

Respuestas

  • Buenos dias Fer:
    Ante todo darte las gracias, hemos implementado una solucion intermedia, pero la idea nos la propiciastes tu con tu idea de implementar una interfaz intermedia, hemos generado una libreria interfaz entre el programa de reflexion y la clase a la que accedemos y en principio va bien.



    Un saludo.Manuel
    miércoles, 12 de diciembre de 2007 11:25
  •  ercegri Escribió:
    Buenos dias Fer:
    Ante todo darte las gracias, hemos implementado una solucion intermedia, pero la idea nos la propiciastes tu con tu idea de implementar una interfaz intermedia, hemos generado una libreria interfaz entre el programa de reflexion y la clase a la que accedemos y en principio va bien.



    Un saludo.Manuel

     

    Hola,

     

    esta es una excelente noticia, por favor no olvides de marcar la solución dada de la interfaz como respuesta correcta temporal.

     

    Saludos,

    miércoles, 12 de diciembre de 2007 12:19

Todas las respuestas

  •  ercegri Escribió:
    Buenas tardes:
    Tengo un problema, que no consigo resolver:
    Estoy tratando de leer los atributos mediante reflexion, consigo leer los atributos pero no puedo hacer un conver al tipo de atributo, para poder acceder a las propiedades que lleva el atributo.
    Mi codigo es el siguiente:

    object[] atributosPropios = tipoTipo.GetCustomAttributes(tipo1 , false);
     foreach (System.Attribute atributo in atributosPropios)
                {
                    string sNombre=((NombreTablaAttribute)atributo).nombreTabla;
                }


    el problema lo tengo que NombreTablaAttribute es el tipo de atributo, pero tengo que obtener ese tipo tambien por reflexion, ya que este ejecutable es el de actualizacion y debe ser independiente de todas las librerias del proyecto, y vamos a acceder a dicha informacion por reflexion.


    Muchas gracias

     

    Hola, a ver si puedo ayudar,

     

    te cuento que no va a ser posible en tiempo de diseño que veas dichas propiedades si el Type del Attribute, o sea NombreTablaAttribute, también lo estás recuperando por Reflection. Imagino que desde ya el compilador de C# te está avisando de dicha situación.

    Algo como lo que tu código busca se podría hacer en VB que es LateBinding, o sea, que hasta que no está en tiempo de ejecución no chequea la asignación a la variable de referencia.

    Si estás atado a C#, vas a tener que accesar a la propiedad .nombreTabla también por Reflection o bien, hacer una interfaz(INombreTabla) con la propiedad nombreTabla, que implemente tu attribute NombreTablaAttribute y que el Cast sea por dicha interface, creo que esta segunda opción si se acopla a tus necesidades podría ser la mas sana.

     

    Bloque de código

    using System;

    using System.Collections.Generic;

    namespace testconsole

    {

    public interface INombreTabla

    {

    string nombreTabla { get; }

    }

    public class NombreTablaAttriute : Attribute, INombreTabla

    {

    public string nombreTabla{get { return "MiTabla"; }}

    }

    class Program

    {

    static void Main(string[] args)

    {

    List<Attribute> atributosPropios = new List<Attribute>();

    atributosPropios.Add(new NombreTablaAttriute());

    foreach (Attribute att in atributosPropios)

    {

    Console.WriteLine(((INombreTabla)att).nombreTabla);

    }

    Console.ReadKey();

    }

    }

    }

     

 

Si te he podido ayudar, por favor no olvides marcar la solución dada como  respuesta correcta.

 

Saludos,

martes, 11 de diciembre de 2007 14:13
  • He intentado lo que me comentas , pero me encuentro con el mismo problema de la interfaz que con el atributo, como bien dices voy a tener que acceder a la propiedad .nombreTabla por reflection , y ahi esta el problema.

    Te cuento un poquito mas, la definicion del atributo y la interfaz la tengo en una libreria independiente, y donde tengo que acceder para obtener el nombre tabla es un ejecutable que solo actua por reflection, por tanto sea para la interfaz o sea para el atributo tengo que acceder por reflexion, que es lo que no encuentro. O quizas no he entendido del todo tu idea de interfaz, que he de reconocer que al ver la idea, pensaba que lo iba a resolver, pero he llegado al mismo callejon sin salida.


    Muchas gracias de antemano fer.
    Un saludo . Manuel
    martes, 11 de diciembre de 2007 16:34
  •  ercegri Escribió:
    He intentado lo que me comentas , pero me encuentro con el mismo problema de la interfaz que con el atributo, como bien dices voy a tener que acceder a la propiedad .nombreTabla por reflection , y ahi esta el problema.

    Te cuento un poquito mas, la definicion del atributo y la interfaz la tengo en una libreria independiente, y donde tengo que acceder para obtener el nombre tabla es un ejecutable que solo actua por reflection, por tanto sea para la interfaz o sea para el atributo tengo que acceder por reflexion, que es lo que no encuentro. O quizas no he entendido del todo tu idea de interfaz, que he de reconocer que al ver la idea, pensaba que lo iba a resolver, pero he llegado al mismo callejon sin salida.


    Muchas gracias de antemano fer.
    Un saludo . Manuel

     

    Hola, a ver si puedo ayudar,

     

    Te paso el ejemplo tal cual lo estarías solicitando, pero "creo" que deberías hacer lo de la interfaz sacando dicha interfaz del assembly que solo accedes por Reflection de forma tal de hacer referencia al assembly de la interfaz en el assembly donde tenes los attributos propios y donde vas a estar iterando para sus propiedades. Pero bueno de todas formas para lo que solicitaste debajo te dejo el código...

     

    Bloque de código

    using System;

    using System.Reflection;

    using System.Collections;

    namespace testconsole

    {

    public class NombreTablaAttriute : Attribute

    {

    public string nombreTabla{get { return "MiTabla"; }}

    }

    class Program

    {

    static void Main(string[] args)

    {

    ArrayList atributosPropios = new ArrayList();

    atributosPropios.Add(new NombreTablaAttriute());

    foreach (Attribute att in atributosPropios)

    {

    foreach (PropertyInfo pI in att.GetType().GetProperties())

    {

    if (pI.Name.ToUpper() == "NOMBRETABLA")

    Console.WriteLine(pI.GetValue(att, null));

    }

    }

    Console.ReadKey();

  • }

    }

    }

     

     

     

    Si se conoce efectivamente el nombre de la propiedad y estamos seguros que todos los atributos que estemos recorriendo contarán con ella podemos economizar código de la siguiente manera:

     

    Bloque de código

    using System;

    using System.Reflection;

    using System.Collections;

    namespace testconsole

    {

    public class NombreTablaAttriute : Attribute

    {

    public string nombreTabla{get { return "MiTabla"; }}

    }

    class Program

    {

    static void Main(string[] args)

    {

    ArrayList atributosPropios = new ArrayList();

    atributosPropios.Add(new NombreTablaAttriute());

    foreach (Attribute att in atributosPropios)

    {

    Console.WriteLine(att.GetType().GetProperty("nombreTabla").GetValue(att,null));

    }

    Console.ReadKey();

    }

    }

    }

    }

     

    Si te he podido ayudar, por favor no olvides marcar la solución dada como respuesta correcta.

     

    Saludos,

     

     

    martes, 11 de diciembre de 2007 17:27
  • att.GetType().GetProperties esta opcion por reflexion solo me devuelve la propiedad  TypeId, por lo que no tengo disponible por reflexion la propiedad nombreTabla directamente.

    Es que creo, que te he liado, la situacion inamobible es:

    El atributo y todas sus propiedades (y si quieres la interfaz) deben estar en unas librerias que son las que accedo por reflexion.
    El ejecutable que toma toda la informacion, no puede tener ningun using a ninguna libreria (solo se alimenta del reflexion)


    Entonces de esta manera, no puede hacer una interfaz que accedo desde otro lado,tendria que hacerlo por reflexion que no se como se hace o con using que esto no lo puedo hacer.

    Gracias.
    martes, 11 de diciembre de 2007 17:49
  •  ercegri Escribió:
    att.GetType().GetProperties esta opcion por reflexion solo me devuelve la propiedad  TypeId, por lo que no tengo disponible por reflexion la propiedad nombreTabla directamente.

    Es que creo, que te he liado, la situacion inamobible es:

    El atributo y todas sus propiedades (y si quieres la interfaz) deben estar en unas librerias que son las que accedo por reflexion.
    El ejecutable que toma toda la informacion, no puede tener ningun using a ninguna libreria (solo se alimenta del reflexion)


    Entonces de esta manera, no puede hacer una interfaz que accedo desde otro lado,tendria que hacerlo por reflexion que no se como se hace o con using que esto no lo puedo hacer.

    Gracias.

     

    Hola, a ver si puedo ayudar,

     

    Entonces el attribute que estas interando en ese momento no es NombreTablaAttribute ya que solo posee TypeId, propiedad de la clase Attribute base. Agregale a tu código lo siguiente para asegurarte que el attribute que estas consultando sus propiedades es NombreTablaAttribute

     

    Bloque de código

    Console.WriteLine(att.ToString()); //te devolverá el nombre de la clase que hereda de attribute

     

     

    Dejo aca debajo unas preguntas que deberíamos hacernos para ver si estamos en el camino correcto:

     

    ¿Qué nombre te sale?

    ¿Estarás obteniendo en un tu arreglo de atributos los correctos?

    ¿Y sobre la clase deseada?

    ¿Tu clase NombreTablaAttribute tiene implemetado de forma pública la propiedad nombreTabla? ¿es una property y no un field?

     

    Si te he podido ayudar, por favor no olvides de marcar la solución dado como respuesta correcta.

     

    Saludos,

    martes, 11 de diciembre de 2007 17:56
  • Buenos dias, con respecto a las preguntas que me haces , todo lo que estoy sacando creo que es lo correcto, porque esta esta ya funcionando el unico problema que tengo es quitar las referencias de using de las librerias para hacerlo todo por reflexion no obstante , creo que el codigo es la mejor explicacion:

    MI definicion de atributo: Esto en una libreria fuera del codigo
    [System.AttributeUsage(System.AttributeTargets.Class)]
            public class NombreTablaAttribute : System.Attribute
            {
                public string nombreTabla;

                public NombreTablaAttribute(string nombre)
                {
                    this.nombreTabla = nombre;
                }
            }





    Y en mi codigo accedo al atributo por reflexion (en un ejecutable independiente)

    Assembly ensamblado = Assembly.LoadFrom(@"C:\MILibreria.dll");
    Type tipoTabla = ensamblado.GetType("MiLibreria.Clase+NombreTablaAttribute");
    object[] atributosPropios = tipo.GetCustomAttributes(tipoTabla, false);
                   

                    foreach (Attribute atributo in atributosPropios)
                    {
                                    string prueba=(Clase.NombreTablaAttribute)atributo).nombreTabla
                    }


    El problema de reflexion es esta ultima conversion :
    string prueba=(Clase.NombreTablaAttribute)atributo).nombreTabla
    Ya que al no tener el using de la clase no puedo hacer (Clase.NombreTablaAttribute)atributo).nombreTabla

    Un saludo.
    Muchas gracias.
    miércoles, 12 de diciembre de 2007 7:32
  • Buenos dias Fer:
    Ante todo darte las gracias, hemos implementado una solucion intermedia, pero la idea nos la propiciastes tu con tu idea de implementar una interfaz intermedia, hemos generado una libreria interfaz entre el programa de reflexion y la clase a la que accedemos y en principio va bien.



    Un saludo.Manuel
    miércoles, 12 de diciembre de 2007 11:25
  •  ercegri Escribió:
    Buenos dias Fer:
    Ante todo darte las gracias, hemos implementado una solucion intermedia, pero la idea nos la propiciastes tu con tu idea de implementar una interfaz intermedia, hemos generado una libreria interfaz entre el programa de reflexion y la clase a la que accedemos y en principio va bien.



    Un saludo.Manuel

     

    Hola,

     

    esta es una excelente noticia, por favor no olvides de marcar la solución dada de la interfaz como respuesta correcta temporal.

     

    Saludos,

    miércoles, 12 de diciembre de 2007 12:19
  •  ercegri Escribió:
    Buenos dias, con respecto a las preguntas que me haces , todo lo que estoy sacando creo que es lo correcto, porque esta esta ya funcionando el unico problema que tengo es quitar las referencias de using de las librerias para hacerlo todo por reflexion no obstante , creo que el codigo es la mejor explicacion:

    MI definicion de atributo: Esto en una libreria fuera del codigo
    [System.AttributeUsage(System.AttributeTargets.Class)]
            public class NombreTablaAttribute : System.Attribute
            {
                public string nombreTabla;

                public NombreTablaAttribute(string nombre)
                {
                    this.nombreTabla = nombre;
                }
            }





    Y en mi codigo accedo al atributo por reflexion (en un ejecutable independiente)

    Assembly ensamblado = Assembly.LoadFrom(@"C:\MILibreria.dll");
    Type tipoTabla = ensamblado.GetType("MiLibreria.Clase+NombreTablaAttribute");
    object[] atributosPropios = tipo.GetCustomAttributes(tipoTabla, false);
                   

                    foreach (Attribute atributo in atributosPropios)
                    {
                                    string prueba=(Clase.NombreTablaAttribute)atributo).nombreTabla
                    }


    El problema de reflexion es esta ultima conversion :
    string prueba=(Clase.NombreTablaAttribute)atributo).nombreTabla
    Ya que al no tener el using de la clase no puedo hacer (Clase.NombreTablaAttribute)atributo).nombreTabla

    Un saludo.
    Muchas gracias.

     

    Hola, a ver si puedo ayudar,

     

    leyendo el post que hiciste mostrando el código, me encuentro con que una de las preguntas estaba respondiendo a nuestro problema, por lo que la vuelvo a exponer:

     

    ¿es una property y no un field?

    En el código expuesto nombreTabla es un Field y no una Property.

    Por ende, para que ante un GetProperties tu clase responda a dicho estímulo, tu clase debería ser así(marco en rojo el faltante):

     

    Bloque de código

    [System.AttributeUsage(System.AttributeTargets.Class)]

    public class NombreTablaAttribute : System.Attribute

    {

    private string nombreTabla;

    public string NombreTabla

    {

    get { return nombreTabla; }

    set { nombreTabla = value; }

    }

    public NombreTablaAttribute(string nombre)

    {

    this.nombreTabla = nombre;

    }

    }

     

     

    Por favor, si esta es la solución final marcala como respuesta correcta definitiva mientras que a la de la interfaz deberías marcarla como respuesta correcta temporal.

     

    De todas a formas,el esquema que tomaron como temporal me parece el mas correcto, o sea, el de la intefaz, garantizando los contratos de los atributos.

     

    Saludos,

     

    miércoles, 12 de diciembre de 2007 12:31