2017-02-20 22 views
0

Я работаю над VSPackage, который должен генерировать простые классы из некоторых данных в БД. У меня уже есть статический метод GetFieldInfo, который получает данные, которые мне нужны из БД, и GetFieldInfo возвращает мне List<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 непонятные ошибки (например: Class, delegate, enum, interface or struct expected по линии 2, колонка 9; } expected по линии 7, колонка 9; method must have a return value по линии 15, столбец 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) 
      { 

      } 
     #> 
    } 
}