Crear procesadores de directivas personalizadas para las plantillas de texto T4

El proceso de transformación de plantillas de texto toma un archivo de plantilla de texto como entrada y genera un archivo de texto como salida. El motor de transformación de plantillas de texto controla el proceso y el motor interactúa con un host de transformación de plantillas de texto y uno o varios procesadores de directivas de plantilla de texto para completar el proceso. Para más información, consulte El proceso de transformación plantilla de texto.

Para crear un procesador de directivas personalizado, crea una clase que herede de DirectiveProcessor o RequiresProvidesDirectiveProcessor.

La diferencia entre ambos es que DirectiveProcessor implementa la interfaz mínima necesaria para obtener parámetros del usuario y generar el código que crea el archivo de salida de la plantilla. RequiresProvidesDirectiveProcessor implementa el patrón de diseño de requires/provides. RequiresProvidesDirectiveProcessor controla dos parámetros especiales, requires y provides. Por ejemplo, un procesador de directivas personalizadas podría aceptar un nombre de archivo del usuario, abrir y leer el archivo y, después, almacenar el texto del archivo en una variable denominada fileText. Una subclase de la clase RequiresProvidesDirectiveProcessor podría tomar un nombre de archivo del usuario como valor del parámetro requires y el nombre de la variable en la que almacenar el texto como valor del parámetro provides. Este procesador abriría y leería el archivo y, después, almacenaría el texto del archivo en la variable especificada.

Antes de llamar a un procesador de directivas personalizadas desde una plantilla de texto en Visual Studio, debe registrarlo.

Para más información sobre cómo agregar la clave del Registro, consulte Implementación de un procesador de directivas personalizadas.

Directivas personalizadas

Así es una directiva personalizada:

<#@ MyDirective Processor="MyDirectiveProcessor" parameter1="value1" ... #>

Puede usar un procesador de directivas personalizadas cuando desee acceder a datos externos o recursos desde una plantilla de texto.

Las distintas plantillas de texto pueden compartir la funcionalidad que proporciona un único procesador de directivas, por lo que los procesadores de directivas proporcionan una manera de factorizar el código para su reutilización. La directiva include integrada es similar, ya que puede usarla para simplificar el código y compartirla entre diferentes plantillas de texto. La diferencia es que todas las funcionalidades que proporcione la directiva include es fija y no acepta parámetros. Si desea proporcionar una funcionalidad común a una plantilla de texto y permitir que la plantilla use parámetros, debe crear un procesador de directivas personalizadas.

Estos pueden ser algunos ejemplos de procesadores de directivas personalizadas:

  • Un procesador de directivas para devolver datos de una base de datos que acepta un nombre de usuario y una contraseña como parámetros.

  • Procesador de directivas para abrir y leer un archivo que acepta el nombre del archivo como parámetro.

Partes principales de un procesador de directivas personalizadas

Para desarrollar un procesador de directivas, debe crear una clase que herede de DirectiveProcessor o RequiresProvidesDirectiveProcessor.

Los métodos DirectiveProcessor más importantes que debe implementar son los siguientes.

  • bool IsDirectiveSupported(string directiveName): devuelve true si el procesador de directivas puede tratar con la directiva con nombre.

  • void ProcessDirective (string directiveName, IDictionary<string, string> arguments): el motor de plantillas llama a este método en cada aparición de una directiva en la plantilla. El procesador debe guardar los resultados.

Después de todas las llamadas a ProcessDirective() el motor de plantillas llamará a estos métodos:

  • string[] GetReferencesForProcessingRun(): devuelve los nombres de los ensamblados que requiere el código de plantilla.

  • string[] GetImportsForProcessingRun(): devuelve los espacios de nombres que se pueden usar en el código de plantilla.

  • string GetClassCodeForProcessingRun(): devuelve el código de los métodos, propiedades y otras declaraciones que el código de plantilla puede usar. La forma más fácil de hacerlo es crear una cadena que contenga el código de C# o Visual Basic. Para que el procesador de directivas pueda llamarse desde una plantilla que use cualquier lenguaje CLR, puede construir las instrucciones en forma de árbol CodeDom y, después, devolver el resultado de serializar el árbol en el lenguaje usado por la plantilla.

  • Para más información, consulte Tutorial: Creación de un procesador de directivas personalizadas.