2017-02-20 7 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、9欄、2行目にClass, delegate, enum, interface or struct expected、9欄15行にmethod must have a return value、コラム18)を吐き出していると率直に言って、私もしませんどこで点検を始めるべきかを知る。多くの奇妙なエラーがあるとき、私の勇気は私に伝えます。それは通常、devが追加/設定するのを忘れていた単純なもののためですが、これまで私は何か助けになるものは見つかりませんでした。そして、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"#>を追加します。

第2に、生成されたコードでたくさんの "using"ステートメントを使いたいのです。それらをテキストとしてテンプレートに入れる必要があります。

VSPackageについて - テンプレートのコンパイルとコード生成の2つの段階があり、最初または両方の段階を実行する2つのカスタムツールがあることを覚えておいてください。パッケージが使用されている場合は、開発段階でのテンプレートのコンパイルとテンプレートの実行が必要な場合がほとんどです。

ヒント:テンプレートが想定したことをしなかった場合 - テンプレートを単純化して基本的に - 同じ静的コードを何度も生成させてください。

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) 
      { 

      } 
     #> 
    } 
} 
関連する問題