David
David

Reputation: 2556

Type cannot be found from T4 template

I want to go through all values of the following enum

namespace T4Demo
{
  public enum Ord
  {
    First,
    Second
  }
}

in my template

<#@ template debug="true" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".txt" #>
<# 
  var arr = System.Enum.GetValues(typeof(System.DayOfWeek));
  foreach(var it in arr)
  {
    string name = it.ToString();
    string value = ((int)it).ToString();
#>
    <#= name #>(<#= value #>)
<#
  }
#>

in order to output them. It works fine with System.DayOfWeek and outputs

Sunday(0)
Monday(1)
Tuesday(2)
Wednesday(3)
Thursday(4)
Friday(5)
Saturday(6)

but trying to use Ord instead results in an error saying that the type or namespace 'Ord' cannot be found. If I prefix it with T4Demo. or if I add <#@ import namespace="T4Demo" #> in the template it tells me that 'T4Demo' cannot be found. What have I overlooked?

EDIT:

This is what IntelliSense gives me when trying to enter T4Demo. My own types do not get listed here... So I must be missing some using etc.

IntelliSense

Upvotes: 0

Views: 645

Answers (3)

David
David

Reputation: 2556

As Nicolas Repiquet pointed out, the T4 template is a program on its own. The resolution was consequently to add <#@ assembly name="$(TargetPath)" #> in the template header which makes all my types from the same project visible within the template.

Important to know is the fact that whenever the project is changed and recompiled the template will not be rerun. So in my case, whenever I change the enum in code, I compile and select 'Run custom tool' from the context menu of the template file in the Solution Explorer to ensure that the output of my template matches the enum changes in code.

Upvotes: 0

Nicolas Repiquet
Nicolas Repiquet

Reputation: 9255

Your T4 template is a program on its own, and the types you defined in your main program are not part of it.

There is no easy way to get around that. You might use the T4 include directive to include the enum code in the template code, but you'll probably gonna fight with it a little.

Upvotes: 1

Teun Vos
Teun Vos

Reputation: 584

Try specifing the exact location of your enum, just like you did with the day of the week Arry.

System.Enum.GetValues(typeof(System.DayOfWeek));

Should then become

System.Enum.GetValues(typeof(MyEnumLocation.Ord));

Edit

<#@ template debug="true" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".txt" #>
@model <#= ViewDataTypeName #> // Added this line
<# 
  var arr = System.Enum.GetValues(typeof(System.DayOfWeek)); // This line is no longer required
  foreach(var item in model) // Changed this line
  {
    string name = item.ToString();
    string value = ((int)it).ToString();
#>
    <#= name #>(<#= value #>)
<#
  }
#>

Upvotes: 0

Related Questions