2010-10-13 3 views
9

Gibt es eine Möglichkeit, die ich in einem Namespace lesen kann und durch alle Klassen in einer T4-Vorlage durch Reflexion oder etwas?Klassen in einem Namespace in einer T4-Vorlage lesen

<#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); 
} 
<#} #> 

Beispiel Meta-Daten:

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; } 
    } 
} 

gewünschte Ausgabe:

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); 
    } 
+0

http://www.dreamincode.net/code/snippet1539.htm – eiu165

Antwort

13

Erste T4Toolbox from here

anschließend sicher in Ihrer Vorlage installieren Sie die folgenden Zeilen an der Spitze haben:

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

Dann füge diese Codezeilen hinzu:

<#+ 

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); 
      } 

     } 
    } 
} 
#> 

Dann Sie so alle Klassen in einem Namensraum durch den Aufruf (der zweite Parameter filtert alle Klassen, die ihren Namen den übergebenen String enthalten) finden:

FindClasses("NameSpace.SubNameSpace",""))//All classes in the specifed namespace 

ODER

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

- ---------------------------------------- UPDATE FÜR VS 2012 ------ --------------------

Verwenden Sie diese Funktionen und Namespaces, wenn Ihre T4Toolbox für VS 2 aktualisiert wurde 012:

//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); 
} 

so wird die Suche so etwas wie dieses:

FindClasses(GetDefaultNamespace(),"Repository","RepositoryBase") 
+0

Hinweis: In VS2012 'TransformationContext 'hat sich geändert: http://www.olegsych.com/2012/12/t4-toolbox-for-visual-studio-2012/ – kamranicus

+1

@subkamran ja! Ich werde die Post mit 2012 Version so schnell wie möglich korrigieren ... –

+0

Ich benutze VS2012 mit Ihrem aktualisierten Code und enthalten EnvDTE.dll in meinem Projekt, aber es sagt 'IVsSolution',' SVsSolution', 'IVsHierarchy' kann nicht gefunden werden die .tt Datei. Irgendwelche Ideen? – JimmyBoh

0
+0

Links zu möglichen Lösungen sind immer willkommen, aber bitte fügen Sie einige Details für zukünftige Besucher hinzu, falls der Link ist nicht mehr verfügbar –

1

I T4 in einem .net Kernprojekt verwenden,

Mein T4 ist ziemlich groß, so dass nur die relevanten Informationen zu extrahieren hier .. [In meinem Fall ich suche Entity Framework Models und ich weiß, das sind die einzigen Klassen im Namensraum sind, müssen Sie Ihre eigene, um herauszufiltern]

Referenzierung diese nuget Pakete:

<#@ assembly name="$(UserProfile)\.nuget\packages\Microsoft.VisualStudio.TextTemplating.Interfaces.14.0\14.3.25407\lib\net45\Microsoft.VisualStudio.TextTemplating.Interfaces.14.0.dll" #> 
<#@ assembly name="$(UserProfile)\.nuget\packages\Microsoft.VisualStudio.TextTemplating.14.0\14.3.25407\lib\net45\Microsoft.VisualStudio.TextTemplating.14.0.dll" #> 

diese Importe/includes:

<#@ import namespace="EnvDTE" #> 
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #> 
<#@ import namespace="Microsoft.VisualStudio.TextTemplating.Interfaces" #> 
<#@ include file="$(UserProfile)\.nuget\packages\T4.VsAutomationHelper\1.0.0\tools\ttinc\VsAutomationHelper.CS.ttinclude" #> 
<#@ include file="$(UserProfile)\.nuget\packages\T4.TemplateFileManager\2.2.1\tools\ttinc\TemplateFilemanager.CS.ttinclude" #> 

ich diese Methode haben:

// Get all CodeClass Items in specified namespace 
    public List<EnvDTE.CodeClass> GetClassesInNameSpace(IEnumerable<ProjectItem> items, string nameSpace) 
    { 
     var classItems = new List<EnvDTE.CodeClass>(); 

     var csFileProjectItems = items.Where(d => d.Properties.Item("FullPath").Value.ToString().EndsWith(".cs")); 

     foreach(ProjectItem csFileProjectItem in csFileProjectItems) 
     { 
      EnvDTE.FileCodeModel model = csFileProjectItem.FileCodeModel; 
      foreach(var modelCodeElements in model.CodeElements) 
      { 
       if (modelCodeElements is EnvDTE.CodeNamespace) 
       { 
        var codeNameSpace = ((EnvDTE.CodeNamespace)modelCodeElements); 

        if (codeNameSpace.FullName == nameSpace) 
        { 
         foreach(var modelCodeElementChild in codeNameSpace.Children) 
         { 
          if (modelCodeElementChild is EnvDTE.CodeClass) 
          { 
           classItems.Add((EnvDTE.CodeClass)modelCodeElementChild); 
          } 
         } 
        } 
       } 
      } 
     } 
     return classItems; 
    } 

und nennen Sie es mit: ("App.Data.Model.Entities" mit Ihrem eigenen ersetzen)

var projectItems = this.dteHelper.GetAllProjectItems(); 
     var entityClasses = GetClassesInNameSpace(projectItems, "App.Data.Model.Entities"); 

    foreach (var entityClass in entityClasses) 
    { 
     // entityClass.Name 

     // Important for .NetCore 
     // when calling fileManager.StartNewFile() specify all the parameters, its didn't work for me otherwise eg: 
     // code appreciated (file manager created before following code) 

     var fileProperties = new FileProperties() 
{ 
    BuildAction = BuildAction.Compile 
}; 
     fileManager.StartNewFile(dataAccessFileName, generatedFilesTargetProject, generatedFilesTargetFolder, fileProperties); 
    fileManager.IsAutoIndentEnabled = true; 
    fileManager.CanOverwriteExistingFile = true; 
    } 
+0

Woher kommt dteHelper? – Cesar

Verwandte Themen