다음을 통해 공유


T4 텍스트 템플릿 작성 지침

이 일반적인 지침은 Visual Studio에서 프로그램 코드나 기타 애플리케이션 리소스를 생성하는 경우 도움이 될 수 있습니다. 고정 규칙은 아닙니다.

디자인 타임 T4 템플릿에 대한 지침

디자인 타임 T4 템플릿은 디자인 타임에 Visual Studio 프로젝트에서 코드를 생성하는 템플릿입니다. 자세한 내용은 T4 텍스트 템플릿을 사용하여 디자인 타임 코드 생성을 참조하세요.

애플리케이션의 다양한 측면을 생성합니다.

코드 생성은 프로젝트 중에 변경될 수 있거나 애플리케이션의 다른 버전 간에 변경될 애플리케이션 측면에 가장 유용합니다. 생성해야 하는 항목을 보다 쉽게 확인할 수 있도록 이러한 가변적인 측면을 비가변적인 측면에서 분리합니다. 예를 들어 애플리케이션에서 웹 사이트를 제공하는 경우 한 페이지에서 다른 페이지로 탐색 경로를 정의하는 논리에서 함수를 제공하는 표준 페이지를 분리합니다.

하나 이상의 원본 모델에서 가변적인 측면을 인코딩합니다.

모델은 생성되는 코드의 가변적인 부분에 대한 특정 값을 얻기 위해 각 템플릿에서 읽는 파일 또는 데이터베이스입니다. 모델은 데이터베이스, 고유한 디자인의 XML 파일, 다이어그램 또는 도메인 특정 언어가 될 수 있습니다. 일반적으로 한 모델은 Visual Studio 프로젝트에서 많은 파일을 생성하는 데 사용됩니다. 각 파일은 별도의 템플릿에서 생성됩니다.

하나 이상의 모델을 프로젝트에 사용할 수 있습니다. 예를 들어 웹 페이지 간 탐색을 위한 모델과 페이지 레이아웃에 대한 별도의 모델을 정의할 수 있습니다.

사용자의 요구 사항 및 어휘를 구현하지 않고 모델에 집중합니다.

예를 들어 웹 사이트 애플리케이션에서 모델이 웹 페이지 및 하이퍼링크를 참조하게 될 것입니다.

모델에서 나타내는 정보의 종류에 맞는 프레젠테이션 형태를 선택하는 것이 가장 좋습니다. 예를 들어 웹 사이트를 통한 탐색 경로 모델은 상자와 화살표의 다이어그램일 수 있습니다.

생성된 코드를 테스트합니다.

수동 또는 자동화된 테스트를 사용하여 사용자가 요구하는 결과 코드가 작동하는지 확인합니다. 코드가 생성되는 동일한 모델에서 테스트를 생성하지 않습니다.

일부 경우에는 모델에서 직접 일반 테스트를 수행할 수 있습니다. 예를 들어 웹 사이트의 페이지를 탐색하여 해당 웹 사이트의 모든 페이지에 도달할 수 있는지 확인하는 테스트를 작성할 수 있습니다.

사용자 지정 코드 허용: partial 클래스를 생성합니다.

생성된 코드와 함께 직접 작성하는 코드를 허용합니다. 일반적으로 코드 생성 체계에서 발생할 수 있는 모든 변형에 대해 설명할 수 있는 것은 아닙니다. 따라서 생성된 코드의 일부를 추가하거나 재정의해야 합니다. 생성된 자료가 C# 또는 Visual Basic과 같은 .NET 언어인 경우 다음 두 가지 전략이 특히 유용합니다.

  • 생성된 클래스는 partial이어야 합니다. 이렇게 하면 생성된 코드에 콘텐츠를 추가할 수 있습니다.

  • 클래스는 다른 클래스에서 상속하는 쌍으로 생성되어야 합니다. 기본 클래스는 생성된 모든 메서드와 속성을 포함해야 하며, 파생 클래스는 생성자만 포함해야 합니다. 이를 통해 직접 작성한 코드는 생성된 메서드를 재정의할 수 있습니다.

XML과 같은 다른 생성 언어에서는 <#@include#> 지시문을 사용하여 직접 작성한 콘텐츠와 생성된 콘텐츠를 간단하게 조합합니다. 더 복잡한 경우에는 생성된 파일을 직접 작성한 파일과 결합하는 후처리 단계를 작성해야 할 수 있습니다.

공통 자료를 포함 파일 또는 런타임 템플릿으로 이동합니다.

여러 템플릿에서 비슷한 텍스트와 코드 블록을 반복하지 않도록 하려면 <#@ include #> 지시문을 사용합니다. 자세한 내용은 T4 Include 지시문을 참조하세요.

별도의 프로젝트에서 런타임 텍스트 템플릿을 빌드한 다음 디자인 타임 템플릿에서 호출할 수도 있습니다. 이렇게 하려면 <#@ assembly #> 지시문을 사용하여 별도의 프로젝트에 액세스합니다.

코드의 많은 블록을 별도 어셈블리로 이동하는 것이 좋습니다.

코드 블록과 클래스 기능 블록이 큰 경우 이 코드 중 일부를 별도의 프로젝트에서 컴파일하는 메서드로 이동하는 것이 유용할 수 있습니다. <#@ assembly #> 지시문을 사용하여 템플릿의 코드에 액세스할 수 있습니다. 자세한 내용은 T4 Assembly 지시문을 참조하세요.

템플릿이 상속할 수 있는 추상 클래스에 메서드를 포함할 수 있습니다. 추상 클래스는 Microsoft.VisualStudio.TextTemplating.TextTransformation에서 상속해야 합니다. 자세한 내용은 T4 템플릿 지시문을 참조하세요.

구성 파일이 아닌 코드를 생성합니다.

가변적인 애플리케이션을 작성하는 한 가지 방법은 구성 파일을 허용하는 제네릭 프로그램 코드를 작성하는 것입니다. 이러한 방식으로 작성된 애플리케이션은 매우 유연하며 비즈니스 요구 사항이 변경되면 애플리케이션을 다시 작성하지 않고도 다시 구성할 수 있습니다. 그러나 이 방법의 단점은 애플리케이션이 보다 구체적인 애플리케이션보다 더 잘 수행되지 않는다는 것입니다. 또한 대부분의 제네릭 형식을 처리하기 때문에 일부 프로그램 코드는 읽기 및 유지 관리가 더 어려워집니다.

이와 대조적으로 컴파일 전에 가변 부분을 생성하는 애플리케이션은 강력한 형식의 애플리케이션입니다. 이를 통해 직접 작성 코드를 작성하고 소프트웨어의 생성된 부분과 통합하는 것이 훨씬 쉽고 안정적입니다.

코드 생성의 모든 이점을 얻으려면 구성 파일 대신 프로그램 코드를 생성해 봅니다.

Generated Code 폴더를 사용합니다.

Generated Code라는 프로젝트 폴더에 템플릿과 생성된 파일을 저장하여 직접 편집해야 하는 파일이 아니라는 것을 명확히 합니다. 생성된 클래스를 재정의하거나 생성된 클래스에 추가할 사용자 지정 코드를 만드는 경우 이러한 클래스를 Custom Code라는 폴더에 저장합니다. 일반적인 프로젝트의 구조는 다음과 같습니다.

MyProject
   Custom Code
      Class1.cs
      Class2.cs
   Generated Code
      Class1.tt
          Class1.cs
      Class2.tt
          Class2.cs
   AnotherClass.cs

런타임(전처리) T4 템플릿에 대한 지침

공통 자료를 상속된 템플릿으로 이동합니다.

상속을 사용하여 T4 텍스트 템플릿 간에 메서드 및 텍스트 블록을 공유할 수 있습니다. 자세한 내용은 T4 템플릿 지시문을 참조하세요.

런타임 템플릿이 있는 포함 파일을 사용할 수도 있습니다.

코드의 많은 본문을 partial 클래스로 이동합니다.

각 런타임 템플릿은 템플릿과 이름이 같은 partial 클래스 정의를 생성합니다. 동일한 클래스의 다른 부분 정의가 포함된 코드 파일을 작성할 수 있습니다. 이러한 방식으로 클래스에 메서드, 필드 및 생성자를 추가할 수 있습니다. 이러한 멤버는 템플릿의 코드 블록에서 호출할 수 있습니다.

IntelliSense를 사용할 수 있기 때문에 코드를 더 쉽게 작성할 수 있다는 이점이 있습니다. 또한 프레젠테이션과 기본 논리를 더 잘 구분할 수 있습니다.

예를 들어, MyReportText.tt:

The total is: <#= ComputeTotal() #>

MyReportText-Methods.cs:

private string ComputeTotal() { ... }

사용자 지정 코드 허용: 확장 포인트를 제공합니다.

<#+ 클래스 기능 블록 #>에서 가상 메서드를 생성하는 것이 좋습니다. 이렇게 하면 단일 템플릿을 수정하지 않고 많은 컨텍스트에서 사용할 수 있습니다. 템플릿을 수정하는 대신 최소 추가 논리를 제공하는 파생 클래스를 생성할 수 있습니다. 파생 클래스는 일반 코드이거나 런타임 템플릿이 될 수 있습니다.

예를 들어 MyStandardRunTimeTemplate.tt에서 다음과 같습니다.

This page is copyright <#= CompanyName() #>.
<#+ protected virtual string CompanyName() { return ""; } #>

애플리케이션 코드에서 다음과 같습니다.

class FabrikamTemplate : MyStandardRunTimeTemplate
{
  protected override string CompanyName() { return "Fabrikam"; }
}
...
  string PageToDisplay = new FabrikamTemplate().TextTransform();

모든 T4 템플릿에 대한 지침

텍스트 생성에서 데이터 수집을 분리합니다.

계산과 텍스트 블록을 혼합해서 사용하지 않아야 합니다. 각 텍스트 템플릿에서 첫 번째 <# 코드 블록 #>을 사용하여 변수를 설정하고 복잡한 계산을 수행합니다. 첫 번째 텍스트 블록부터 템플릿의 끝까지 또는 첫 번째 <#+ 클래스 기능 블록 #>까지 긴 식을 사용하지 않고, 텍스트 블록이 포함되어 있지 않은 경우 루프와 조건문을 방지합니다. 이 방법을 사용하면 템플릿을 더 쉽게 읽고 유지 관리할 수 있습니다.

포함 파일에 .tt를 사용하지 않습니다.

포함 파일의 경우 .ttinclude와 같은 다른 파일 이름 확장명을 사용합니다. 런타임 또는 디자인 타임 텍스트 템플릿으로 처리하려는 파일에만 .tt를 사용합니다. 경우에 따라 Visual Studio는 .tt 파일을 인식하고 처리를 위해 해당 속성을 자동으로 설정합니다.

각 템플릿을 고정 프로토타입으로 시작합니다.

생성하려는 코드 또는 텍스트의 예제를 작성하고 올바른지 확인합니다. 그런 다음 확장명을 .tt로 변경하고 모델을 읽어 내용을 수정하는 코드를 증분식으로 삽입합니다.

형식화된 모델을 사용하는 것이 좋습니다.

모델에 대해 XML 또는 데이터베이스 스키마를 만들 수 있지만 DSL(도메인 특정 언어)을 만드는 것이 유용할 수 있습니다. DSL은 스키마의 각 노드를 나타내는 클래스와 특성을 나타내는 속성을 생성한다는 이점이 있습니다. 즉, 비즈니스 모델을 기준으로 프로그래밍할 수 있습니다. 예시:

Team Members:
<# foreach (Person p in team.Members)
 { #>
    <#= p.Name #>
<# } #>

모델에 다이어그램을 사용하는 것이 좋습니다.

대부분의 모델은 특히 매우 큰 경우 텍스트 테이블로 가장 효과적으로 표시되고 관리됩니다.

그러나 일부 비즈니스 요구 사항에 대해서는 복잡한 관계 및 작업 흐름 집합을 명확히 파악하는 것이 중요하며 다이어그램이 가장 적합한 매체입니다. 다이어그램의 장점은 사용자 및 기타 관련자와 논의하기가 쉽기 때문입니다. 비즈니스 요구 사항의 수준에서 모델의 코드를 생성하면 요구 사항이 변경될 때 코드를 보다 유연하게 만들 수 있습니다.

사용자 고유의 다이어그램 유형을 DSL(도메인 특정 언어)로 디자인할 수도 있습니다. UML 및 DSL 모두에서 코드를 생성할 수 있습니다. 자세한 내용은 아키텍처 분석 및 모델링을 참조하세요.