DirectiveProcessor – třída
Abstraktní základní třída pro konkrétní směrnice procesoru.
Hierarchie dědičnosti
Object
Microsoft.VisualStudio.TextTemplating.DirectiveProcessor
Microsoft.VisualStudio.TextTemplating.ParameterDirectiveProcessor
Microsoft.VisualStudio.TextTemplating.RequiresProvidesDirectiveProcessor
Obor názvů: Microsoft.VisualStudio.TextTemplating
Sestavení: Microsoft.VisualStudio.TextTemplating.12.0 (v Microsoft.VisualStudio.TextTemplating.12.0.dll)
Syntaxe
'Deklarace
Public MustInherit Class DirectiveProcessor _
Implements IDirectiveProcessor
public abstract class DirectiveProcessor : IDirectiveProcessor
public ref class DirectiveProcessor abstract : IDirectiveProcessor
[<AbstractClass>]
type DirectiveProcessor =
class
interface IDirectiveProcessor
end
public abstract class DirectiveProcessor implements IDirectiveProcessor
Typ DirectiveProcessor zveřejňuje následující členy.
Konstruktory
Název | Popis | |
---|---|---|
DirectiveProcessor | Při přepsání v odvozené třídě inicializuje novou instanci DirectiveProcessor třídy. |
Nahoru
Vlastnosti
Název | Popis | |
---|---|---|
Errors | Získá chyby, ke kterým došlo při zpracování direktivy. |
Nahoru
Metody
Název | Popis | |
---|---|---|
Equals | Určuje, zda je zadaný objekt rovna aktuální objekt. (Zděděno z Object.) | |
Finalize | Umožňuje objektu k pokusu uvolnit prostředky a provádět další operace vyčištění před je zažádáno systémem uvolňování paměti. (Zděděno z Object.) | |
FinishProcessingRun | Při přepsání v odvozené třídě ukončí kolo směrnice zpracování. | |
GetClassCodeForProcessingRun | Při přepsání v odvozené třídě získá kód, chcete-li přidat třídy vygenerované transformace. | |
GetHashCode | Slouží jako výchozí funkce hash. (Zděděno z Object.) | |
GetImportsForProcessingRun | Při přepsání v odvozené třídě získá obory názvů, které chcete importovat do třídy vygenerované transformace. | |
GetPostInitializationCodeForProcessingRun | Při přepsání v odvozené třídě získá kód přidat na konec metoda inicializace třídy vygenerované transformace. | |
GetPreInitializationCodeForProcessingRun | Při přepsání v odvozené třídě získá kód přidejte na začátek metoda inicializace třídy vygenerované transformace. | |
GetReferencesForProcessingRun | Při přepsání v odvozené třídě získá odkazy předat kompilátor třídy vygenerované transformace. | |
GetTemplateClassCustomAttributes | Získáte všechny vlastní atributy do třídy šablony. | |
GetType | Získá Type aktuální instance. (Zděděno z Object.) | |
Initialize | Při přepsání v odvozené třídě, inicializuje instanci procesoru. | |
IsDirectiveSupported | Při přepsání v odvozené třídě, určí, zda směrnice procesoru podporuje určené směrnicí. | |
MemberwiseClone | Vytvoří mělká kopie aktuálního Object. (Zděděno z Object.) | |
ProcessDirective | Při přepsání v odvozené třídě zpracovává jediné směrnice ze souboru šablony. | |
StartProcessingRun | Při přepsání v odvozené třídě spustí kolo směrnice zpracování. | |
ToString | Vrátí řetězec, který představuje aktuální objekt. (Zděděno z Object.) |
Nahoru
Explicitní implementace rozhraní
Název | Popis | |
---|---|---|
IDirectiveProcessor.Errors | ||
IDirectiveProcessor.RequiresProcessingRunIsHostSpecific | ||
IDirectiveProcessor.SetProcessingRunIsHostSpecific |
Nahoru
Poznámky
Text šablony transformačního procesu probíhá ve dvou krocích.V prvním kroku stroj transformace textu šablony vytvoří třídu, která je označována jako třídy vygenerované transformace.V druhém kroku motor zkompiluje a spustí třídy vygenerované transformace, vyprodukovat výstup generovaný text.
Směrnice procesory pracují přidáním kódu do třídy vygenerované transformace.Zavolejte směrnic z textu šablony a po zavolání směrnice zbytek kódu, který napíšete do textu šablony lze spoléhat na funkce poskytované touto směrnicí.Můžete napsat vlastní vlastní směrnice procesorů pro poskytnutí vlastní funkcionality pro text šablony.
Další informace naleznete v tématu Vytváření vlastních procesorů pro direktivy textových šablon T4.
Modul transformace textu šablony budou konat singleton instance všechny požadované DirectiveProcessor třídy.
DirectiveProcessorimplementuje stavový stroj.
Například text má-li šablona tři volání směrnice procesoru stejné směrnice, zavolá motoru následující metody v uvedeném pořadí:
StartProcessingRun
Příklady
Následující příklad vytvoří vlastní směrnice procesoru.Vlastní směrnice procesoru obsahuje směrnice, který čte soubor XML.Směrnice ukládá data XML v XmlDocument proměnné a vystavuje XmlDocument prostřednictvím vlastnosti.
Další informace naleznete v tématu Návod: Vytvoření vlastního procesoru direktiv.
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using Microsoft.VisualStudio.TextTemplating;
namespace CustomDP
{
public class CustomDirectiveProcessor : DirectiveProcessor
{
//this buffer stores the code that is added to the
//generated transformation class after all the processing is done
//---------------------------------------------------------------------
private StringBuilder codeBuffer;
//Using a Code Dom Provider creates code for the
//generated transformation class in either Visual Basic or C#.
//If you want your directive processor to support only one language, you
//can hard code the code you add to the generated transformation class.
//In that case, you do not need this field.
//--------------------------------------------------------------------------
private CodeDomProvider codeDomProvider;
//this stores the full contents of the text template that is being processed
//--------------------------------------------------------------------------
private String templateContents;
//These are the errors that occur during processing. The engine passes
//the errors to the host, and the host can decide how to display them,
//for example the the host can display the errors in the UI
//or write them to a file.
//---------------------------------------------------------------------
private CompilerErrorCollection errorsValue;
public new CompilerErrorCollection Errors
{
get { return errorsValue; }
}
//Each time this directive processor is called, it creates a new property.
//We count how many times we are called, and append "n" to each new
//property name. The property names are therefore unique.
//-----------------------------------------------------------------------------
private int directiveCount = 0;
public override void Initialize(ITextTemplatingEngineHost host)
{
//we do not need to do any initialization work
}
public override void StartProcessingRun(CodeDomProvider languageProvider, String templateContents, CompilerErrorCollection errors)
{
//the engine has passed us the language of the text template
//we will use that language to generate code later
//----------------------------------------------------------
this.codeDomProvider = languageProvider;
this.templateContents = templateContents;
this.errorsValue = errors;
this.codeBuffer = new StringBuilder();
}
//Before calling the ProcessDirective method for a directive, the
//engine calls this function to see whether the directive is supported.
//Notice that one directive processor might support many directives.
//---------------------------------------------------------------------
public override bool IsDirectiveSupported(string directiveName)
{
if (string.Compare(directiveName, "CoolDirective", StringComparison.OrdinalIgnoreCase) == 0)
{
return true;
}
if (string.Compare(directiveName, "SuperCoolDirective", StringComparison.OrdinalIgnoreCase) == 0)
{
return true;
}
return false;
}
public override void ProcessDirective(string directiveName, IDictionary<string, string> arguments)
{
if (string.Compare(directiveName, "CoolDirective", StringComparison.OrdinalIgnoreCase) == 0)
{
string fileName;
if (!arguments.TryGetValue("FileName", out fileName))
{
throw new DirectiveProcessorException("Required argument 'FileName' not specified.");
}
if (string.IsNullOrEmpty(fileName))
{
throw new DirectiveProcessorException("Argument 'FileName' is null or empty.");
}
//Now we add code to the generated transformation class.
//This directive supports either Visual Basic or C#, so we must use the
//System.CodeDom to create the code.
//If a directive supports only one language, you can hard code the code.
//--------------------------------------------------------------------------
CodeMemberField documentField = new CodeMemberField();
documentField.Name = "document" + directiveCount + "Value";
documentField.Type = new CodeTypeReference(typeof(XmlDocument));
documentField.Attributes = MemberAttributes.Private;
CodeMemberProperty documentProperty = new CodeMemberProperty();
documentProperty.Name = "Document" + directiveCount;
documentProperty.Type = new CodeTypeReference(typeof(XmlDocument));
documentProperty.Attributes = MemberAttributes.Public;
documentProperty.HasSet = false;
documentProperty.HasGet = true;
CodeExpression fieldName = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), documentField.Name);
CodeExpression booleanTest = new CodeBinaryOperatorExpression(fieldName, CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(null));
CodeExpression rightSide = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("XmlReaderHelper"), "ReadXml", new CodePrimitiveExpression(fileName));
CodeStatement[] thenSteps = new CodeStatement[] { new CodeAssignStatement(fieldName, rightSide) };
CodeConditionStatement ifThen = new CodeConditionStatement(booleanTest, thenSteps);
documentProperty.GetStatements.Add(ifThen);
CodeStatement s = new CodeMethodReturnStatement(fieldName);
documentProperty.GetStatements.Add(s);
CodeGeneratorOptions options = new CodeGeneratorOptions();
options.BlankLinesBetweenMembers = true;
options.IndentString = " ";
options.VerbatimOrder = true;
options.BracingStyle = "C";
using (StringWriter writer = new StringWriter(codeBuffer, CultureInfo.InvariantCulture))
{
codeDomProvider.GenerateCodeFromMember(documentField, writer, options);
codeDomProvider.GenerateCodeFromMember(documentProperty, writer, options);
}
}//end CoolDirective
//One directive processor can contain many directives.
//If you want to support more directives, the code goes here...
//-----------------------------------------------------------------
if (string.Compare(directiveName, "supercooldirective", StringComparison.OrdinalIgnoreCase) == 0)
{
//code for SuperCoolDirective goes here...
}//end SuperCoolDirective
//Track how many times the processor has been called.
//-----------------------------------------------------------------
directiveCount++;
}//end ProcessDirective
public override void FinishProcessingRun()
{
this.codeDomProvider = null;
//important: do not do this:
//the get methods below are called after this method
//and the get methods can access this field
//-----------------------------------------------------------------
//this.codeBuffer = null;
}
public override string GetPreInitializationCodeForProcessingRun()
{
//Use this method to add code to the start of the
//Initialize() method of the generated transformation class.
//We do not need any pre-initialization, so we will just return "".
//-----------------------------------------------------------------
//GetPreInitializationCodeForProcessingRun runs before the
//Initialize() method of the base class.
//-----------------------------------------------------------------
return String.Empty;
}
public override string GetPostInitializationCodeForProcessingRun()
{
//Use this method to add code to the end of the
//Initialize() method of the generated transformation class.
//We do not need any post-initialization, so we will just return "".
//------------------------------------------------------------------
//GetPostInitializationCodeForProcessingRun runs after the
//Initialize() method of the base class.
//-----------------------------------------------------------------
return String.Empty;
}
public override string GetClassCodeForProcessingRun()
{
//Return the code to add to the generated transformation class.
//-----------------------------------------------------------------
return codeBuffer.ToString();
}
public override string[] GetReferencesForProcessingRun()
{
//This returns the references that we want to use when
//compiling the generated transformation class.
//-----------------------------------------------------------------
//We need a reference to this assembly to be able to call
//XmlReaderHelper.ReadXml from the generated transformation class.
//-----------------------------------------------------------------
return new string[]
{
"System.Xml",
this.GetType().Assembly.Location
};
}
public override string[] GetImportsForProcessingRun()
{
//This returns the imports or using statements that we want to
//add to the generated transformation class.
//-----------------------------------------------------------------
//We need CustomDP to be able to call XmlReaderHelper.ReadXml
//from the generated transformation class.
//-----------------------------------------------------------------
return new string[]
{
"System.Xml",
"CustomDP"
};
}
}//end class CustomDirectiveProcessor
//-------------------------------------------------------------------------
// the code that we are adding to the generated transformation class
// will call this method
//-------------------------------------------------------------------------
public static class XmlReaderHelper
{
public static XmlDocument ReadXml(string fileName)
{
XmlDocument d = new XmlDocument();
using (XmlTextReader reader = new XmlTextReader(fileName))
{
try
{
d.Load(reader);
}
catch (System.Xml.XmlException e)
{
throw new DirectiveProcessorException("Unable to read the XML file.", e);
}
}
return d;
}
}//end class XmlReaderHelper
}//end namespace CustomDP
Imports System
Imports System.CodeDom
Imports System.CodeDom.Compiler
Imports System.Collections.Generic
Imports System.Globalization
Imports System.IO
Imports System.Text
Imports System.Xml
Imports System.Xml.Serialization
Imports Microsoft.VisualStudio.TextTemplating
Namespace CustomDP
Public Class CustomDirectiveProcessor
Inherits DirectiveProcessor
'this buffer stores the code that is added to the
'generated transformation class after all the processing is done
'---------------------------------------------------------------
Private codeBuffer As StringBuilder
'Using a Code Dom Provider creates code for the
'generated transformation class in either Visual Basic or C#.
'If you want your directive processor to support only one language, you
'can hard code the code you add to the generated transformation class.
'In that case, you do not need this field.
'--------------------------------------------------------------------------
Private codeDomProvider As CodeDomProvider
'this stores the full contents of the text template that is being processed
'--------------------------------------------------------------------------
Private templateContents As String
'These are the errors that occur during processing. The engine passes
'the errors to the host, and the host can decide how to display them,
'for example the the host can display the errors in the UI
'or write them to a file.
'---------------------------------------------------------------------
Private errorsValue As CompilerErrorCollection
Public Shadows ReadOnly Property Errors() As CompilerErrorCollection
Get
Return errorsValue
End Get
End Property
'Each time this directive processor is called, it creates a new property.
'We count how many times we are called, and append "n" to each new
'property name. The property names are therefore unique.
'--------------------------------------------------------------------------
Private directiveCount As Integer = 0
Public Overrides Sub Initialize(ByVal host As ITextTemplatingEngineHost)
'we do not need to do any initialization work
End Sub
Public Overrides Sub StartProcessingRun(ByVal languageProvider As CodeDomProvider, ByVal templateContents As String, ByVal errors As CompilerErrorCollection)
'the engine has passed us the language of the text template
'we will use that language to generate code later
'----------------------------------------------------------
Me.codeDomProvider = languageProvider
Me.templateContents = templateContents
Me.errorsValue = errors
Me.codeBuffer = New StringBuilder()
End Sub
'Before calling the ProcessDirective method for a directive, the
'engine calls this function to see whether the directive is supported.
'Notice that one directive processor might support many directives.
'---------------------------------------------------------------------
Public Overrides Function IsDirectiveSupported(ByVal directiveName As String) As Boolean
If String.Compare(directiveName, "CoolDirective", StringComparison.OrdinalIgnoreCase) = 0 Then
Return True
End If
If String.Compare(directiveName, "SuperCoolDirective", StringComparison.OrdinalIgnoreCase) = 0 Then
Return True
End If
Return False
End Function
Public Overrides Sub ProcessDirective(ByVal directiveName As String, ByVal arguments As IDictionary(Of String, String))
If String.Compare(directiveName, "CoolDirective", StringComparison.OrdinalIgnoreCase) = 0 Then
Dim fileName As String
If Not (arguments.TryGetValue("FileName", fileName)) Then
Throw New DirectiveProcessorException("Required argument 'FileName' not specified.")
End If
If String.IsNullOrEmpty(fileName) Then
Throw New DirectiveProcessorException("Argument 'FileName' is null or empty.")
End If
'Now we add code to the generated transformation class.
'This directive supports either Visual Basic or C#, so we must use the
'System.CodeDom to create the code.
'If a directive supports only one language, you can hard code the code.
'--------------------------------------------------------------------------
Dim documentField As CodeMemberField = New CodeMemberField()
documentField.Name = "document" & directiveCount & "Value"
documentField.Type = New CodeTypeReference(GetType(XmlDocument))
documentField.Attributes = MemberAttributes.Private
Dim documentProperty As CodeMemberProperty = New CodeMemberProperty()
documentProperty.Name = "Document" & directiveCount
documentProperty.Type = New CodeTypeReference(GetType(XmlDocument))
documentProperty.Attributes = MemberAttributes.Public
documentProperty.HasSet = False
documentProperty.HasGet = True
Dim fieldName As CodeExpression = New CodeFieldReferenceExpression(New CodeThisReferenceExpression(), documentField.Name)
Dim booleanTest As CodeExpression = New CodeBinaryOperatorExpression(fieldName, CodeBinaryOperatorType.IdentityEquality, New CodePrimitiveExpression(Nothing))
Dim rightSide As CodeExpression = New CodeMethodInvokeExpression(New CodeTypeReferenceExpression("XmlReaderHelper"), "ReadXml", New CodePrimitiveExpression(fileName))
Dim thenSteps As CodeStatement() = New CodeStatement() {New CodeAssignStatement(fieldName, rightSide)}
Dim ifThen As CodeConditionStatement = New CodeConditionStatement(booleanTest, thenSteps)
documentProperty.GetStatements.Add(ifThen)
Dim s As CodeStatement = New CodeMethodReturnStatement(fieldName)
documentProperty.GetStatements.Add(s)
Dim options As CodeGeneratorOptions = New CodeGeneratorOptions()
options.BlankLinesBetweenMembers = True
options.IndentString = " "
options.VerbatimOrder = True
options.BracingStyle = "VB"
Using writer As StringWriter = New StringWriter(codeBuffer, CultureInfo.InvariantCulture)
codeDomProvider.GenerateCodeFromMember(documentField, writer, options)
codeDomProvider.GenerateCodeFromMember(documentProperty, writer, options)
End Using
End If 'CoolDirective
'One directive processor can contain many directives.
'If you want to support more directives, the code goes here...
'-----------------------------------------------------------------
If String.Compare(directiveName, "supercooldirective", StringComparison.OrdinalIgnoreCase) = 0 Then
'code for SuperCoolDirective goes here
End If 'SuperCoolDirective
'Track how many times the processor has been called.
'-----------------------------------------------------------------
directiveCount += 1
End Sub 'ProcessDirective
Public Overrides Sub FinishProcessingRun()
Me.codeDomProvider = Nothing
'important: do not do this:
'the get methods below are called after this method
'and the get methods can access this field
'-----------------------------------------------------------------
'Me.codeBuffer = Nothing
End Sub
Public Overrides Function GetPreInitializationCodeForProcessingRun() As String
'Use this method to add code to the start of the
'Initialize() method of the generated transformation class.
'We do not need any pre-initialization, so we will just return "".
'-----------------------------------------------------------------
'GetPreInitializationCodeForProcessingRun runs before the
'Initialize() method of the base class.
'-----------------------------------------------------------------
Return String.Empty
End Function
Public Overrides Function GetPostInitializationCodeForProcessingRun() As String
'Use this method to add code to the end of the
'Initialize() method of the generated transformation class.
'We do not need any post-initialization, so we will just return "".
'------------------------------------------------------------------
'GetPostInitializationCodeForProcessingRun runs after the
'Initialize() method of the base class.
'-----------------------------------------------------------------
Return String.Empty
End Function
Public Overrides Function GetClassCodeForProcessingRun() As String
'Return the code to add to the generated transformation class.
'-----------------------------------------------------------------
Return codeBuffer.ToString()
End Function
Public Overrides Function GetReferencesForProcessingRun() As String()
'This returns the references that we want to use when
'compiling the generated transformation class.
'-----------------------------------------------------------------
'We need a reference to this assembly to be able to call
'XmlReaderHelper.ReadXml from the generated transformation class.
'-----------------------------------------------------------------
Return New String() {"System.Xml", Me.GetType().Assembly.Location}
End Function
Public Overrides Function GetImportsForProcessingRun() As String()
'This returns the imports or using statements that we want to
'add to the generated transformation class.
'-----------------------------------------------------------------
'We need CustomDP to be able to call XmlReaderHelper.ReadXml
'from the generated transformation class.
'-----------------------------------------------------------------
Return New String() {"System.Xml", "CustomDP"}
End Function
End Class 'CustomDirectiveProcessor
'--------------------------------------------------------------------------
' the code that we are adding to the generated transformation class
' will call this method
'--------------------------------------------------------------------------
Public Class XmlReaderHelper
Public Shared Function ReadXml(ByVal fileName As String) As XmlDocument
Dim d As XmlDocument = New XmlDocument()
Using reader As XmlTextReader = New XmlTextReader(fileName)
Try
d.Load(reader)
Catch e As System.Xml.XmlException
Throw New DirectiveProcessorException("Unable to read the XML file.", e)
End Try
End Using
Return d
End Function
End Class 'XmlReaderHelper
End Namespace
Bezpečný přístup z více vláken
Všechny veřejné členy static (Shared v jazyce Visual Basic) tohoto typu jsou bezpečné pro přístup z více vláken. Není zaručeno, že členy instancí jsou bezpečné pro přístup z více vláken.
Viz také
Referenční dokumentace
Microsoft.VisualStudio.TextTemplating – obor názvů
RequiresProvidesDirectiveProcessor
Další zdroje
Vytváření vlastních procesorů pro direktivy textových šablon T4