В настоящее время я пытаюсь сгенерировать некоторые классы на основе интерфейсов, используя t4. Для этого я использую EnvDTE для разбора моего исходного кода. Получение классов и свойств работает нормально, но по какой-то причине я не могу получить доступ к их соответствующим атрибутам.
Мой интерфейс выглядит так:
namespace TestProject.Model
{
[SQLModel]
public interface IEntity
{
[PrimaryKey, AutoIncrement, NotNull]
long? Id { get; set; }
}
}
И шаблон t4 вот так:
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".txt" #>
<#@ assembly name="System" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Data.Entity" #>
<#@ assembly name="EnvDTE" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.IO"#>
<#@ import namespace="EnvDTE" #>
<#@ include file="T4Toolbox.tt" #>
<#
string targetNamespace = "TestProject";
var dte = (DTE)TransformationContext.Current.GetService(typeof(DTE));
var project = dte.Solution.FindProjectItem(TransformationContext.Current.Host.TemplateFile).ContainingProject;
var classes = FindModelInterfaces(project, targetNamespace, "");
foreach (CodeInterface c in classes) {
var className = GetClassName(c);
#>
public partial class <#= className #> {
<#
IEnumerable<CodeProperty> properties = c.Members.OfType<CodeProperty>()
.Where(p => p.Access.HasFlag(vsCMAccess.vsCMAccessPublic))
.OrderBy(p => p.Name);
foreach (CodeProperty prop in properties) {
var attributes = prop.Attributes.OfType<CodeAttribute>();
foreach (CodeAttribute attribute in attributes) {
#>
<#= attribute.Name #>
<#
}
#>
public <#= prop.Type.AsString #> <#= prop.Name #> { get; set; }
<#
}
#>
}
<#
}
#>
<#+
private string GetClassName(CodeInterface iface) {
if (!iface.Name.StartsWith("I"))
throw new Exception();
return iface.Name.Substring(1);
}
List<CodeInterface> FindModelInterfaces(Project project, string ns, string className) {
List<CodeInterface> result = new List<CodeInterface>();
FindClasses(project.CodeModel.CodeElements, className, ns, result, false);
return result;
}
void FindClasses(CodeElements elements, string className, string searchNamespace, List<CodeInterface> result, bool isNamespaceOk) {
if (elements == null) return;
foreach (CodeElement element in elements) {
if (element is CodeNamespace) {
CodeNamespace ns = element as CodeNamespace;
if (ns.FullName.Contains(searchNamespace))
FindClasses(ns.Members, className, searchNamespace, result, true);
else
FindClasses(ns.Members, className, searchNamespace, result, false);
} else if (element is CodeInterface && isNamespaceOk) {
CodeInterface c = element as CodeInterface;
if (c.FullName.Contains(className))
result.Add(c);
FindClasses(c.Members, className, searchNamespace, result, true);
}
}
}
#>
Несмотря на то, что в свойстве Id явно присутствуют атрибуты, в шаблоне они не возвращаются. Что я делаю не так?