Search code examples
c#asp.net-mvcasp.net-mvc-4t4scaffolding

Read class properties in mvc4 T4 template


I am working on a T4 Template that will generate View Models based on a entities on core. For example I have News class in Core and I want this template to Generate view models like these

public class News
{
    public property int Id {get;set;}
    public property string Title {get;set;}
    public property string Content {get;set;}
}

public class NewsCreate
{
    public property int Id {get;set;}
    public property string Title {get;set;}
    public property string Content {get;set;}
}
public class NewsUpdate
{
    public property int Id {get;set;}
    public property string Title {get;set;}
    public property string Content {get;set;}
} 

for now just these two. but I could not find a way to get the properties of News class. how can I use reflection to get them and . . .


Solution

  • Assuming your "News" class resides inside the same project as you want your views to be created in you've got two possibilities:

    1. Build your project and then reference the output-assembly in the T4 template using <#@ assembly name="$(TargetPath)" #>. Then you can use standard reflection inside the template to reach your desired classes. But be careful, you're always reflecting your last build that might be outdated and/or contain errors!
    2. Have a look at tangible's T4 editor. It's free and provides syntax highlighting + IntelliSense for T4 templates. It has also got a free template gallery containing a template named "tangible VisualStudio Automation Helper". Include this one into your template and use the Visual Studio Code Model to iterate over all classes that are inside your current solution:

      <# var project = VisualStudioHelper.CurrentProject;
      
      // get all class items from the code model
      var allClasses = VisualStudioHelper.GetAllCodeElementsOfType(project.CodeModel.CodeElements, EnvDTE.vsCMElement.vsCMElementClass, false);
      
      // iterate all classes
      foreach(EnvDTE.CodeClass codeClass in allClasses)
      {
          // iterate all properties
          var allProperties = VisualStudioHelper.GetAllCodeElementsOfType(codeClass.Members, EnvDTE.vsCMElement.vsCMElementProperty, true);
          foreach(EnvDTE.CodeProperty property in allProperties)
          {
              // check if it is decorated with an "Input"-Attribute
              if (property.Attributes.OfType<EnvDTE.CodeAttribute>().Any(a => a.FullName == "Input"))
              {
                  ...
              }
          }
      }
      #>
      

    Hope that helps!