2010-10-13 24 views
9

bir ad alanındaki sınıfları okuyarak bir yansıtma veya bir şey kullanarak bir t4 şablonundaki tüm sınıflar arasında geçiş yapabileceğim bir yol var mı?Bir t4 şablonunda

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

örnek meta veriler:

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

istenen çıkışı:

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

cevap

13

İlk T4Toolbox from here

yüklemek Sonra Şablon size, üst kısımda şu satırları olun: CodeProject üzerinde Colin Eberhardt tarafından Bunu yapmanın bir örneği var

Şu kod satırlarını ekleyin:

<#+ 

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

     } 
    } 
} 
#> 

Sonra böyle arayarak ad alanındaki tüm sınıfları bulabilirsiniz (ikinci parametre isimleri geçen dize içeren tüm sınıfları filtreler):

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

VEYA

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

- ---------------------------------------- VS 2012 İÇİN GÜNCELLEME ------ --------------------

T4Toolbox'ınız VS 2 için güncellendiyse bu işlevleri ve ad alanlarını kullanın. 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); 
} 

yapması için arama böyle bir şey olacak:

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

Not (kendinizinkilerle "App.Data.Model.Entities" değiştirin): VS2012 olarak 'TransformationContext 'değişti: http://www.olegsych.com/2012/12/t4-toolbox-for-visual-studio-2012/ – kamranicus

+1

@subkamran evet! Ben 2012 sürümü ile asap düzeltmek olacak ... –

+0

Güncellenmiş kod ile VS2012 kullanıyorum ve projemde EnvDTE.dll dahil, ancak 'IVsSolution', 'SVsSolution',' IVsHierarchy' içinde bulunamıyor .tt dosyası. Herhangi bir fikir? – JimmyBoh

2

Yapabileceğiniz en iyi şey DTE otomasyon API'leri bir parçası olan Visual Studio CodeModel, kullanmaktır. Şablonunuzu HostSpecific yaparak, Host özelliğinizi IServiceProvider'a dönüştürerek ve sonra GetService() çağrısı yaparak DTE'yi alabilirsiniz. Sonra

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

: http://www.codeproject.com/Articles/39071/Declarative-Dependency-Property-Definition-with-T4.aspx

0

Büyük yöntem @Mahmoud Morave tarafından verilir, ama ne yazık ki Çekirdek projeleri için çalışmaz. Ayrılmış bir .NET projesi oluşturmalıydım.

Bir .net çekirdek projesinde T4 kullanıyorum

Errors were generated when initializing the transformation object. The transformation will not be run. Type 'Microsoft.VisualStudio.ProjectSystem.VS.Implementation.Package.ProjectNode' in Assembly 'Microsoft.VisualStudio.ProjectSystem.VS.Implementation, Version= 12\14' is not marked as serializable.

+0

Potansiyel çözümlere olan bağlantılar her zaman bekler, ancak bağlantının olması durumunda lütfen gelecekteki ziyaretçiler için bazı ayrıntılar ekleyin. Artık mevcut değil –

1

,

Benim T4, oldukça büyük bu yüzden sadece burada alakalı bilgi ayıklanması olduğunu ..

başvuran bu Nuget paketleri [Benim durumumda ben Varlık Çerçeve Modelleri arıyorum ve ben bu ad tek sınıfları olduğunu biliyorum, kendi filtrelemek gerekebilir]:

<#@ 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" #> 

bu ithalat/içerir:

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

<#@ 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" #> 

bu yöntemi vardır

ve kullanma diyoruz:

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

dteHelper nereden geliyor? – Cesar