gpt4 book ai didi

t4 - 读取t4模板中命名空间中的类

转载 作者:行者123 更新时间:2023-12-04 03:17:24 27 4
gpt4 key购买 nike

有没有一种方法可以读取 namespace 并使用反射或其他方法遍历t4模板中的所有类?

<#foreach (class poco in LoadNamespace("Web.Code.Entities.Poco").Classes ) { #>
public interface I<# poco.ClassName #>Repository
{
IQueryable< <# poco.ClassName #> > Get();
<# poco.ClassName #> Save(<# poco.ClassName #> entity);
bool Delete(<# poco.ClassName #> entity);
}
<#} #>

元数据示例:
namespace Web.Code.Entities.Poco
{
public class Product
{
public int Id { get; set; }
public string Name{ get; set; }
public string Category{ get; set; }
}

public class Employee
{
public int Id { get; set; }
public string Name{ get; set; }
}
}

所需的输出:
    public interface IProductRepository 
{
IQueryable<Product> Get();
Product Save(Product entity);
bool Delete(Product entity);
}

public interface IEmployeeRepository
{
IQueryable<Employee> Get();
Employee Save(Employee entity);
bool Delete(Employee entity);
}

最佳答案

首先安装T4Toolbox from here

然后在您的模板中确保顶部有以下几行:

<#@ assembly name="EnvDTE" #> 
<#@ import namespace="EnvDTE" #>
<#@ include file="T4Toolbox.tt" #>

然后添加以下代码行:
<#+  

private List<CodeClass> FindClasses(string nameSpace, string className)
{
List<CodeClass> result=new List<CodeClass>();
FindClasses(TransformationContext.Project.CodeModel.CodeElements,className,nameSpace,result,false);
return result;

}


private void FindClasses(CodeElements elements, string className,string searchNamespace,List<CodeClass> result,bool isNamespaceOk)
{
if (elements==null)return;
foreach (CodeElement element in elements)
{
if(element is CodeNamespace)
{
CodeNamespace ns = element as CodeNamespace;
if(ns != null)
{
if (ns.FullName == searchNamespace)
FindClasses(ns.Members, className,searchNamespace,result,true);
else
FindClasses(ns.Members, className,searchNamespace,result,false);
}
}
else if(element is CodeClass && isNamespaceOk)
{
CodeClass c = element as CodeClass;
if (c != null)
{
if(c.FullName.Contains(className))
result.Add(c);

FindClasses(c.Members, className,searchNamespace,result,true);
}

}
}
}
#>

然后,您可以通过这样调用来在 namespace 中找到所有类(第二个参数过滤名称包含传递的字符串的所有类):
FindClasses("NameSpace.SubNameSpace",""))//All classes in the specifed namespace 

或者
FindClasses("NameSpace.SubNameSpace","Repository")) //All classes in the specifed namespace which have "Repository" in their names

------------------------------------------ VS 2012的更新--- -----------------------

如果您的T4Toolbox已针对VS 2012更新,请使用以下函数和 namespace :
//visual studio 2012+
<#@ assembly name="Microsoft.VisualStudio.Shell.11.0" #>
<#@ assembly name="Microsoft.VisualStudio.Shell.Interop" #>
<#@ import namespace="Microsoft.VisualStudio.Shell" #>
<#@ import namespace="Microsoft.VisualStudio.Shell.Interop" #>

private List<CodeClass> FindClasses(string nameSpace, string className,string baseClassName)
{
List<CodeClass> result=new List<CodeClass>();
FindClasses(GetProject().CodeModel.CodeElements,className,baseClassName,nameSpace,result,false);
return result;

}


private void FindClasses(CodeElements elements, string className,string baseClassName,string searchNamespace,List<CodeClass> result,bool isNamespaceOk)
{
if (elements==null)return;
foreach (CodeElement element in elements)
{
if(element is CodeNamespace)
{
CodeNamespace ns = element as CodeNamespace;
if(ns != null)
{
if (ns.FullName == searchNamespace)
FindClasses(ns.Members, className,baseClassName,searchNamespace,result,true);
else
FindClasses(ns.Members, className,baseClassName,searchNamespace,result,false);
}
}
else if(element is CodeClass && isNamespaceOk)
{
CodeClass c = element as CodeClass;
if (c != null)
{
if(c.FullName.Contains(className) && (baseClassName==null || (HasIt(c.Bases ,baseClassName) && c.Name != baseClassName)))
result.Add(c);

FindClasses(c.Members, className,baseClassName,searchNamespace,result,true);
}

}
}
}

private bool HasIt(CodeElements elements,string name)
{
foreach (CodeElement element in elements)
{
if (element.Name==name)
return true;
}
return false;
}

private Project GetProject()
{
// Get DTE
var dte = (DTE)TransformationContext.Current.GetService(typeof(DTE));

// Get ProjectItem representing the template file
ProjectItem projectItem = dte.Solution.FindProjectItem(TransformationContext.Current.Host.TemplateFile);

// Get the Project of the template file
Project project = projectItem.ContainingProject;

return project;
}

private string GetDefaultNamespace()
{

// Get DTE
var dte = (DTE)TransformationContext.Current.GetService(typeof(DTE));

// Get ProjectItem representing the template file
ProjectItem projectItem = dte.Solution.FindProjectItem(TransformationContext.Current.Host.TemplateFile);

// Get the Project of the template file
Project project = projectItem.ContainingProject;

var vsSolution = (IVsSolution)TransformationContext.Current.GetService(typeof(SVsSolution));
IVsHierarchy vsHierarchy;
ErrorHandler.ThrowOnFailure(vsSolution.GetProjectOfUniqueName(project.FullName, out vsHierarchy));
uint projectItemId;
ErrorHandler.ThrowOnFailure(vsHierarchy.ParseCanonicalName(projectItem.FileNames[1], out projectItemId));
object defaultNamespace;
ErrorHandler.ThrowOnFailure(vsHierarchy.GetProperty(projectItemId, (int)VsHierarchyPropID.DefaultNamespace, out defaultNamespace));
return ((string)defaultNamespace);
}

因此您的搜索将如下所示:
FindClasses(GetDefaultNamespace(),"Repository","RepositoryBase")

关于t4 - 读取t4模板中命名空间中的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3924820/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com