dimanche 22 mars 2020

GetType() in a T4 template always returns null

I'm trying to write a T4 template that will generate a partial class file for every model class in the folder. I may be doing this wrong, so please feel free to suggest improvements to the bits that seem to be working.

My test project has a Models folder that contains a couple of simple classes, eg Person.cs contains...

using System;

namespace WithTT.Models {
  public partial class Person {
    public int ID { get; set; }
    public string FirstName { get; set; }
    public string Surname { get; set; }
    // etc...
  }
}

My T4 template (in the same folder) uses the MultipleOutputHelper.ttinclude helper template. The the T4 file currently looks like this...

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ include file="MultipleOutputHelper.ttinclude" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".log" #>

<# var manager = Manager.Create(Host, GenerationEnvironment); #>
<# manager.StartHeader(false); #>
<# manager.EndBlock(); #>

<#
  string folder = this.Host.ResolvePath("."); // get current folder
  folder = folder.Substring(0, folder.Length - 2); // knock the "\." off the end
  // Loop through each file and create an AbcExt.cs partial class
  foreach(string file in Directory.GetFiles(folder, "*.cs").Where(f => !f.EndsWith("Ext.cs")).Select(f => f.Replace(".cs", ""))) {
    manager.StartNewFile($"{file}Ext.cs"); 
    string className = Path.GetFileNameWithoutExtension(file);
    string ns = File.ReadAllLines(file + ".cs").Single(l => l.StartsWith("namespace")).Replace("namespace", "").Replace("{", "").Trim();
#>
// This code was generated from a template, do not modify!
namespace <#=ns#> {
  public partial class <#=className#> {
    // TODO AYS - Write the With() method...
  }
}
<#
manager.EndBlock();
}
#>

<# manager.Process(true); #>

This works fine so far, and produces basic code files that look like this

// This code was generated from a template, do not modify!
namespace WithTT.Models {
  public partial class Person {
    // TODO AYS - Write the With() method...
  }
}

Now, some of the helper methods I need to use to generate the code I want in here require the type of the class in question. Having got hold of the namespace (in the ns variable) and the class name (in the className variable), I expected to be able to do the following...

Type t = Assembly.GetExecutingAssembly().GetType(ns + "." + className);

...or...

Type t = Type.GetType(ns + "." + className);

However, whichever one I use, t is always null. The namespace and class name are fine, as you can see from the generated file, and according to the top two answers to this question, either should work.

If I try the same code in the Program.cs of the test project, I get the type without problem.

Anyone any idea how I can get the Type of the class in question? Thanks





Aucun commentaire:

Enregistrer un commentaire