Sdílet prostřednictvím


Generování textu za běhu pomocí textových šablon T4

Textové řetězce v aplikaci můžete vygenerovat za běhu pomocí textových šablon modulu runtime sady Visual Studio. Počítač, ve kterém se aplikace spouští, nemusí mít sadu Visual Studio. Šablony modulu runtime se někdy nazývají "předzpracované textové šablony", protože v době kompilace generuje kód, který se spouští za běhu.

Každá šablona je směs textu, protože se zobrazí ve vygenerovaném řetězci a fragmenty kódu programu. Fragmenty programu poskytují hodnoty pro proměnné části řetězce a také řídí podmíněné a opakované části.

Například následující šablona může být použita v aplikaci, která vytvoří sestavu HTML.

<#@ template language="C#" #>
<html><body>
<h1>Sales for Previous Month</h2>
<table>
    <# for (int i = 1; i <= 10; i++)
       { #>
         <tr><td>Test name <#= i #> </td>
             <td>Test value <#= i * i #> </td> </tr>
    <# } #>
 </table>
This report is Company Confidential.
</body></html>

Všimněte si, že šablona je stránka HTML, ve které byly části proměnných nahrazeny programovým kódem. Návrh této stránky můžete zahájit napsáním statického prototypu stránky HTML. Potom můžete nahradit tabulku a další části proměnných kódem programu, který generuje obsah, který se liší od jedné příležitosti k další.

Použití šablony ve vaší aplikaci usnadňuje zobrazení konečné formy výstupu, než v případě dlouhé řady příkazů zápisu. Provádění změn ve formě výstupu je jednodušší a spolehlivější.

Vytvoření textové šablony za běhu v libovolné aplikaci

Vytvoření textové šablony za běhu

  1. V Průzkumník řešení v místní nabídce projektu zvolte Přidat>novou položku.

  2. V dialogovém okně Přidat novou položku vyberte šablonu runtime textu. (V jazyce Visual Basic se podívejte do části Obecné společné položky>.)

  3. Zadejte název souboru šablony.

    Poznámka:

    Název souboru šablony se použije jako název třídy ve vygenerovaném kódu. Proto by neměl obsahovat mezery ani interpunkci.

  4. Zvolte položku Přidat.

    Vytvoří se nový soubor s příponou .tt. Vlastnost Vlastní nástroj je nastavena na TextTemplatingFilePreprocessor. Obsahuje následující řádky:

    <#@ template language="C#" #>
    <#@ assembly name="System.Core" #>
    <#@ import namespace="System.Linq" #>
    <#@ import namespace="System.Text" #>
    <#@ import namespace="System.Collections.Generic" #>
    
  5. Přidejte odkaz na balíček NuGet System.CodeDom.

Převod existujícího souboru na šablonu za běhu

Dobrým způsobem, jak vytvořit šablonu, je převést existující příklad výstupu. Pokud například vaše aplikace vygeneruje soubory HTML, můžete začít vytvořením prostého souboru HTML. Ujistěte se, že funguje správně a zda je její vzhled správný. Pak ho zahrňte do projektu sady Visual Studio a převeďte ho na šablonu.

Převod existujícího textového souboru na šablonu za běhu

  1. Zahrňte soubor do projektu sady Visual Studio. V Průzkumník řešení v místní nabídce projektu zvolte Přidat>existující položku.

  2. Nastavte vlastnost Custom Tools souboru na TextTemplatingFilePreprocessor. V Průzkumník řešení v místní nabídce souboru zvolte Vlastnosti.

    Poznámka:

    Pokud je vlastnost již nastavena, ujistěte se, že je TextTemplatingFilePreprocessor a nikoli TextTemplatingFileGenerator. K tomu může dojít, pokud zahrnete soubor, který již má příponu .tt.

  3. Změňte příponu názvu souboru na .tt. I když je tento krok volitelný, pomůže vám vyhnout se otevření souboru v nesprávném editoru.

  4. Odeberte všechny mezery nebo interpunkci z hlavní části názvu souboru. Například "Moje webová Page.tt" by byla nesprávná, ale MyWebPage.tt je správná. Název souboru se použije jako název třídy ve vygenerovaném kódu.

  5. Na začátek souboru vložte následující řádek. Pokud pracujete v projektu jazyka Visual Basic, nahraďte "C#" slovem "VB".

    <#@ template language="C#" #>

  6. Přidejte odkaz na balíček NuGet System.CodeDom.

Obsah šablony za běhu

Direktiva šablony

Při vytváření souboru ponechte první řádek šablony:

<#@ template language="C#" #>

Parametr jazyka bude záviset na jazyce projektu.

Prostý obsah

Upravte soubor .tt tak, aby obsahoval text, který má aplikace generovat. Příklad:

<html><body>
<h1>Sales for January</h2>
<!-- table to be inserted here -->
This report is Company Confidential.
</body></html>

Kód vloženého programu

Kód programu můžete vložit mezi <# a #>. Příklad:

<table>
    <# for (int i = 1; i <= 10; i++)
       { #>
         <tr><td>Test name <#= i #> </td>
             <td>Test value <#= i * i #> </td> </tr>
    <# } #>
 </table>

Všimněte si, že příkazy jsou vloženy mezi <# ... #> výrazy a jsou vloženy mezi <#= ... #>. Další informace naleznete v tématu Psaní textové šablony T4.

Použití šablony

Kód vytvořený ze šablony

Při uložení souboru .tt se vygeneruje podřízený soubor .cs nebo .vb . Chcete-li zobrazit tento soubor v Průzkumník řešení, rozbalte uzel souboru .tt. V projektu jazyka Visual Basic nejprve zvolte Zobrazit všechny soubory na panelu nástrojů Průzkumník řešení.

Všimněte si, že soubor podřízené společnosti obsahuje částečnou třídu, která obsahuje metodu volanou TransformText(). Tuto metodu můžete volat z aplikace.

Generování textu za běhu

V kódu aplikace můžete pomocí volání vygenerovat obsah šablony takto:

MyWebPage page = new MyWebPage();
String pageContent = page.TransformText();
System.IO.File.WriteAllText("outputPage.html", pageContent);

Chcete-li vygenerovanou třídu umístit do určitého oboru názvů, nastavte vlastnost Vlastní nástroj Obor názvů souboru textové šablony.

Ladění textových šablon modulu runtime

Ladit a testovat textové šablony modulu runtime stejným způsobem jako běžný kód.

Zarážku můžete nastavit v textové šabloně. Pokud aplikaci spustíte v režimu ladění ze sady Visual Studio, můžete procházet kód a vyhodnocovat výrazy kukátků obvyklým způsobem.

Předávání parametrů v konstruktoru

Šablona obvykle musí importovat některá data z jiných částí aplikace. Aby to bylo snadné, je kód vytvořený šablonou částečnou třídou. V jiném souboru v projektu můžete vytvořit další část stejné třídy. Tento soubor může obsahovat konstruktor s parametry, vlastnostmi a funkcemi, ke kterým má přístup kód vložený do šablony, a zbytek aplikace.

Můžete například vytvořit samostatný soubor MyWebPageCode.cs:

partial class MyWebPage
{
    private MyData m_data;
    public MyWebPage(MyData data) { this.m_data = data; }}

Do souboru šablony MyWebPage.tt můžete napsat:

<h2>Sales figures</h2>
<table>
<# foreach (MyDataItem item in m_data.Items)
   // m_data is declared in MyWebPageCode.cs
   { #>
      <tr><td> <#= item.Name #> </td>
          <td> <#= item.Value #> </td></tr>
<# } // end of foreach
#>
</table>

Použití této šablony v aplikaci:

MyData data = ...;
MyWebPage page = new MyWebPage(data);
String pageContent = page.TransformText();
System.IO.File.WriteAllText("outputPage.html", pageContent);

Parametry konstruktoru v jazyce Visual Basic

V jazyce Visual Basic obsahuje samostatný soubor MyWebPageCode.vb :

Namespace My.Templates
  Partial Public Class MyWebPage
    Private m_data As MyData
    Public Sub New(ByVal data As MyData)
      m_data = data
    End Sub
  End Class
End Namespace

Soubor šablony může obsahovat:

<#@ template language="VB" #>
<html><body>
<h1>Sales for January</h2>
<table>
<#
    For Each item In m_data.Items
#>
    <tr><td>Test name <#= item.Name #> </td>
      <td>Test value <#= item.Value #> </td></tr>
<#
    Next
#>
</table>
This report is Company Confidential.
</body></html>

Šablonu lze vyvolat předáním parametru v konstruktoru:

Dim data = New My.Templates.MyData
    ' Add data values here ....
Dim page = New My.Templates.MyWebPage(data)
Dim pageContent = page.TransformText()
System.IO.File.WriteAllText("outputPage.html", pageContent)

Předávání dat ve vlastnostech šablony

Alternativním způsobem předání dat do šablony je přidání veřejných vlastností do třídy šablony v částečné definici třídy. Aplikace může nastavit vlastnosti před vyvoláním TransformText().

Do třídy šablony můžete také přidat pole v částečné definici. To vám umožní předávat data mezi po sobě jdoucími spuštěními šablony.

Použití částečných tříd pro kód

Mnoho vývojářů dává přednost tomu, aby se vyhnuli psaní velkých těl kódu v šablonách. Místo toho můžete definovat metody v částečné třídě, která má stejný název jako soubor šablony. Volejte tyto metody ze šablony. Šablona tak jasně ukazuje, jak bude vypadat cílový výstupní řetězec. Diskuze o vzhledu výsledku je možné oddělit od logiky vytváření zobrazených dat.

Sestavení a odkazy

Pokud chcete, aby kód šablony odkazovat na .NET nebo jiné sestavení, jako je System.Xml.dll, přidejte ho do odkazů projektu obvyklým způsobem.

Pokud chcete importovat obor názvů stejným způsobem jako using příkaz, můžete to udělat pomocí direktivy import :

<#@ import namespace="System.Xml" #>

Tyto direktivy musí být umístěny na začátek souboru bezprostředně po směrnici <#@template .

Sdílený obsah

Pokud máte text sdílený mezi několika šablonami, můžete ho umístit do samostatného souboru a zahrnout ho do každého souboru, ve kterém se má zobrazit:

<#@include file="CommonHeader.txt" #>

Zahrnutý obsah může obsahovat libovolnou kombinaci kódu programu a prostého textu a může obsahovat další direktivy include a další direktivy.

Direktivu include lze použít kdekoli v textu souboru šablony nebo zahrnutého souboru.

Dědičnost mezi textovými šablonami za běhu

Obsah mezi šablonami za běhu můžete sdílet napsáním šablony základní třídy, která může být abstraktní. inherits Použijte parametr direktivy <@#template#> k odkazování na jinou třídu šablony modulu runtime.

Model dědičnosti: Fragmenty v základních metodách

V následujícím příkladu si všimněte následujících bodů:

  • Základní třída SharedFragments definuje metody v rámci bloků <#+ ... #>funkcí třídy .

  • Základní třída neobsahuje žádný volný text. Místo toho se všechny jeho textové bloky vyskytují uvnitř metod funkcí třídy.

  • Odvozená třída vyvolá metody definované v SharedFragments.

  • Aplikace volá metodu TextTransform() odvozené třídy, ale ne transformuje základní třídu SharedFragments.

  • Základní i odvozené třídy jsou textové šablony modulu runtime; To znamená, vlastní nástroj vlastnost je nastavena na TextTemplatingFilePreprocessor.

SharedFragments.tt:

<#@ template language="C#" #>
<#+
protected void SharedText(int n)
{
#>
   Shared Text <#= n #>
<#+
}
// Insert more methods here if required.
#>

MyTextTemplate1.tt:

<#@ template language="C#" inherits="SharedFragments" #>
begin 1
   <# SharedText(2); #>
end 1

MyProgram.cs:

...
MyTextTemplate1 t1  = new MyTextTemplate1();
string result = t1.TransformText();
Console.WriteLine(result);

Výsledný výstup:

begin 1
    Shared Text 2
end 1

Vzor dědičnosti: Text v základním textu

V tomto alternativním přístupu k použití dědičnosti šablon je část textu definována v základní šabloně. Odvozené šablony poskytují data a fragmenty textu, které se vejdou do základního obsahu.

AbstractBaseTemplate1.tt:

<#@ template language="C#" #>

Here is the description for this derived template:
  <#= this.Description #>

Here is the fragment specific to this derived template:
<#
  this.PushIndent("  ");
  SpecificFragment(42);
  this.PopIndent();
#>
End of common template.
<#+
  // State set by derived class before calling TextTransform:
  protected string Description = "";
  // 'abstract' method to be defined in derived classes:
  protected virtual void SpecificFragment(int n) { }
#>

DerivedTemplate1.tt:

<#@ template language="C#" inherits="AbstractBaseTemplate1" #>
<#
  // Set the base template properties:
  base.Description = "Description for this derived class";

  // Run the base template:
  base.TransformText();

#>
End material for DerivedTemplate1.

<#+
// Provide a fragment specific to this derived template:

protected override void SpecificFragment(int n)
{
#>
   Specific to DerivedTemplate1 : <#= n #>
<#+
}
#>

Kód aplikace:

...
DerivedTemplate1 t1 = new DerivedTemplate1();
string result = t1.TransformText();
Console.WriteLine(result);

Výsledný výstup:

Here is the description for this derived template:
  Description for this derived class

Here is the fragment specific to this derived template:
     Specific to DerivedTemplate1 : 42
End of common template.
End material for DerivedTemplate1.

Šablony návrhu: Pokud chcete použít šablonu k vygenerování kódu, který se stane součástí vaší aplikace, přečtěte si téma Vytváření kódu v době návrhu pomocí textových šablon T4.

Šablony za běhu lze použít v libovolné aplikaci, kde jsou šablony a jejich obsah určeny v době kompilace. Pokud ale chcete napsat rozšíření sady Visual Studio, které generuje text ze šablon, které se mění za běhu, přečtěte si téma Vyvolání transformace textu v rozšíření VS.