2017-02-20 2 views
0

DB의 일부 데이터에서 간단한 클래스를 생성해야하는 VSPackage에서 작업하고 있습니다. DB에서 필요한 데이터를 가져 오는 정적 메서드 GetFieldInfo을 이미 가지고 있으며 GetFieldInfoList<TableField>을 반환합니다. 여기서 TableField은 필요한 모든 데이터를 보유하는 사용자 정의 클래스입니다.T4로 간단한 클래스를 생성하는 방법은 무엇입니까?

지금까지, 내 ​​T4 템플릿은 다음과 같습니다

<#@ template language="C#" #> 
<#@ assembly name="System.Core" #> 
<#@ import namespace="System" #> 
<#@ import namespace="System.Collections.Generic" #> 
<#@ import namespace="System.Linq" #> 
<#@ import namespace="System.Text" #> 
<#@ import namespace="System.Threading.Tasks" #> 
<#@ output extension=".cs" #> 
<#@ parameter name="namespace" type="System.String" #> 
<#@ parameter name="className" type="System.String" #> 
<#@ parameter name="fields" type="System.Collections.Generic.List<TableField>" #> 

namespace <#= this.namespace #> 
{ 
    public class <#= classname #> 
    { 
     <# 
      foreach (TableField campo in fields) 
      { 

      } 
     #> 
    } 
} 

이 모든 (정적 메소드, 사용자 정의 클래스와 템플릿) 같은 프로젝트 내의 다른 네임 스페이스에 있습니다. 이 프로젝트 ("도우미 프로젝트"라고 부름)는 VSPackage 프로젝트가 아닙니다 (VSPackage 프로젝트에 참조로 추가됨).

내 문제는,이 템플릿은 27 이해할 수없는 오류 (예 :; 7 호선에 } expected, 열 아홉, 라인 2 Class, delegate, enum, interface or struct expected, 열 아홉 라인 (15)에 method must have a return value, 열 18) 밖으로 뱉어하고 솔직히, 난하지 않습니다 확인을 시작할 위치를 알고 있어야합니다. 내 직감은 많은 이상한 오류가있을 때 알려주는데, 보통 개발자가 추가/구성하는 것을 잊어 버린 몇 가지 간단한 작업 때문에 발생하지만 지금까지는 나를 도울 수있는 것을 찾지 못했습니다. 그리고 Google에서는 T4를 통해 클래스를 생성하는 자습서/예제를 찾지 못했습니다.

생성하려는 항목은 무엇입니까? 이것 :

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace [TARGET_PROJECT_NAMESPACE] 
{ 
    public class [TABLE_NAME] 
    { 
     public [FIELD_TYPE] [FIELD_NAME] { get; set; } 
    } 
} 

그래서 내가 뭘 잘못하고 있니?

+0

템플릿에 매개 변수를 사용합니다. 어떻게 그들을 템플릿에 전달할 건가요? – Evk

+0

@evk 나는 아직도 방법을 찾지 못했습니다. 그 [VS 대 템플릿 호스트를 제공합니다] (http://stackoverflow.com/a/4676347/1502310) 사용할 수 있습니다. –

+0

그렇다면 디자인 타임에 출력을 생성 할 필요가 없다는 의미입니다. VS는 디자인 타임에 템플릿을 변형하려고 시도하기 때문에 이러한 오류가 발생하지만 이는 의미가 없습니다. 템플릿을 마우스 오른쪽 버튼으로 클릭하고 속성으로 이동하여 '맞춤 도구'를 삭제하십시오. 템플리트는 여전히 틀릴 수도 있습니다 (예 : 네임 스페이스없이 TableField를 사용하는 경우). 그러나 이것은 또 다른 이야기입니다. – Evk

답변

0

죄송합니다. 덧글을 추가 할 수 없습니다. "50 평판"이 없습니다.

먼저 TableField 및 템플릿에서 사용하는 다른 부분이 정의 된 네임 스페이스를 참조해야합니다. < # @ import namespace = "your.namnespace"#>를 추가하십시오.

두 번째 - 생성 된 코드에서 "사용"문을 많이 사용하려면 텍스트로 템플릿에 넣어야합니다.

VSPackage에 대해 - 템플릿 컴파일과 코드 생성의 두 단계가 있다는 것을 기억하십시오. 먼저 또는 두 단계를 수행하는 두 가지 사용자 지정 도구가 있습니다. 패키지를 사용할 때 개발 단계 및 템플리트 실행시 템플리트 컴파일이 필요합니다.

힌트 : 템플릿이 가정 한대로하지 않은 경우 - 템플릿을 기본으로 단순화하십시오. 동일한 정적 코드를 반복해서 생성하십시오.

1

.tt 파일을 마우스 오른쪽 버튼으로 클릭하고 Custom Tool의 값이 TextTemplatingFilePreProcessor으로 설정되어 있는지 확인하십시오.

새 템플릿을 만들 때 보일러 플레이트 코드는 클래스를 생성해야합니다. 예를 들어 템플릿 이름을 StackOverflowTemplate.tt으로 지정한 경우 StackOverflowTemplate 클래스가 있어야합니다.

는 당신과 같이 템플릿에 매개 변수를 추가 할 StackOverflowTemplate 클래스를 인스턴스화 할 수 있습니다

Program.cs

public class Program 
{ 
    static void Main(string[] args) 
    { 
     List<TableField> fields = new List<TableField>(); 

     StackOverflowTemplate sft = new StackOverflowTemplate(); 
     sft.Session = new Dictionary<string, object>(); 
     sft.Session.Add("_namespace", "TargetProjectNamespace"); 
     sft.Session.Add("className", "ClassName"); 
     sft.Session.Add("fields", fields); 
     sft.Initialize(); 
     string output = sft.TransformText(); 
     Console.WriteLine(output); 
     Console.ReadKey(); 
    } 
} 

StackOverflowTemplate합니다.tt

<#@ template language="C#" #> 
<#@ parameter name="_namespace" type="System.String" #> 
<#@ parameter name="className" type="System.String" #> 
<#@ parameter name="fields" type="System.Collections.Generic.List<TableField>" #> 
namespace <#= _namespace #> 
{ 
    public class <#= className #> 
    { 
     <# 
      foreach (TableField campo in fields) 
      { 

      } 
     #> 
    } 
} 
관련 문제