Pregunta

Fondo

Tengo algunos scripts que se ejecutan como parte de mi proceso de compilación que miran los diversos archivos de código fuente y generan más código fuente para mí.

Los scripts usan CodeDom para generarlos y leen los archivos .cs usando un simple lector de texto.

Pregunta

Uno de los scripts busca el uso de un atributo de clase específico llamado PageMenuItem y su propósito es construir una lista estática de elementos del menú de la página.

Hace esto ahora leyendo todos los archivos .cs y busca los atributos " PageMenuItem " , luego cuenta el número de argumentos e intenta calcular determinar qué constructor se está utilizando para que pueda separar las diversas piezas de información.

Hay 7 constructores para PageMenuItem con varios parámetros, por lo que es muy difícil determinar a partir del código fuente .cs qué constructor se está utilizando y, por lo tanto, cómo analizar la información.

En lugar de intentar analizar el texto yo mismo, me gustaría simplemente construir un objeto PageMenuItem en la memoria y luego usar sus propiedades.

Entonces, necesito una forma de tomar la declaración de atributo del archivo .cs y construir una nueva instancia de PageMenuItem a partir de ella.

¿Es eso posible?


Otra forma de hacer esta pregunta:

Dada esta cadena:

string myCodeStatement = "[MyAttribute(\"asdf\", \"foo\")]";

¿Cómo puedo crear un objeto del tipo MyAttribute para poder trabajar con ese objeto? Tengo acceso completo al código fuente que define MyAttribute .

¿Fue útil?

Solución 4

Este script es parte del proceso de compilación, por lo que debe ser bastante rápido. Además, genera código fuente que se va a compilar, por lo que quiero evitar la "compilación doble". mi proyecto.

Tampoco quiero tener que compilar y cargar un ensamblaje solo para reflexionar sobre él, lo que parece "caro". hacer varios cientos de veces durante mi proceso de compilación.

Decidí que solo necesitaba arreglar cómo estoy analizando los atributos ahora. ---

Ya estoy leyendo el código fuente e intento contar la cantidad de atributos. Decidí que podía modificar ese código para analizar los argumentos en sus tipos y luego usar Activator.CreateInstance () usando mis argumentos analizados. El activador descubrirá qué constructor usar y obtendré una instancia de mi clase de atributo y puedo usar sus propiedades.

Ya sé qué tipos están disponibles en el constructor del atributo, así que escribí un pequeño método que analiza las cosas entre los parans en su tipo correcto (string, int, guid, etc.) y luego paso esa matriz de objetos al Activador.

El Activador hace el trabajo duro de encontrar el constructor correcto y me devuelve una instancia de mi clase de atributo.

Otros consejos

Parece que podría introspectar los archivos de clase, o alternativamente agregar una anotación al constructor que haría su trabajo de análisis más simple. Las técnicas orientadas a aspectos pueden ayudar: capture cada vez que se llama a ese constructor y, tal como está, agregue el elemento a su lista.

Puede usar el CSharpCodeProvider para hacer esta. Hay un artículo de Soporte de Microsoft que describe el proceso.

¿Invocar al compilador es una opción? Puede crear los archivos de origen ellos mismos y usar la reflexión para recorrer los atributos, o puede crear un archivo de origen ficticio que marque con esos atributos. De cualquier manera, una vez que se compila, puede reflexionar para acceder a las propiedades del atributo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top