Я пытаюсь написать шаблон T4, который будет генерировать частичный файл класса для каждого класса модели в папке. Возможно, я делаю это неправильно, поэтому, пожалуйста, не стесняйтесь предлагать улучшения для битов, которые, кажется, работают.
В моем тестовом проекте есть папка Models, которая содержит пару простых классов, например, Person.cs
содержит. ..
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...
}
}
Мой шаблон T4 (в той же папке) использует вспомогательный шаблон MultipleOutputHelper.ttinclude . Файл T4 в настоящее время выглядит следующим образом ...
<#@ 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); #>
До сих пор это прекрасно работает и создает базовые c файлы кода, которые выглядят следующим образом
// This code was generated from a template, do not modify!
namespace WithTT.Models {
public partial class Person {
// TODO AYS - Write the With() method...
}
}
Теперь некоторые из вспомогательных методов, которые мне нужно использовать для генерации кода, который я здесь хочу, требуется тип рассматриваемого класса. Завладев пространством имен (в переменной ns
) и именем класса (в переменной className
), я ожидал, что смогу сделать следующее ...
Type t = Assembly.GetExecutingAssembly().GetType(ns + "." + className);
.. .or ...
Type t = Type.GetType(ns + "." + className);
Однако, какой бы я ни использовал, t
всегда равен нулю. Пространство имен и имя класса в порядке, как вы можете видеть из сгенерированного файла, и согласно двум верхним ответам на этот вопрос , любой из них должен работать.
Если я попробую тот же код в Program.cs тестового проекта я получаю тип без проблем.
Кто-нибудь знает, как я могу получить Type
рассматриваемого класса? Спасибо
Редактировать Я понял, почему тип всегда нулевой. Если я выведу пространство имен сборки в вывод, скажем так:
// <#=Assembly.GetExecutingAssembly().FullName#>
... тогда я вижу TemporaryT4Assembly, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
, что явно не то же самое, что сборка, которая содержит классы. Теперь моя проблема - выяснить, как получить сборку проекта, а не сгенерированную из шаблона T4