razorcode-generationrazorenginedotliquidscriban

Are there any issues with using Razor as a object-oriented code generator?


I've been experimenting with T4 templates to generate code for classes with methods and attributes. While it's serves my purpose, it's missing some highly desirable productivity features such as syntax highlighting, snippets and Templates on the Macintosh. The trend seems to be moving away from T4. I've encountered the same issues with other templating markup engine such as Scriban and Liquid,

Razor template appears to be an alternative, but it appears more geared towards generating HTML markup code. It's also unclear whether it's syntax collides with the target code output regions, and if outputting code as separate files is straightforward. Can Razor generate object-oriented code and operate outside the context of a web application?


Solution

  • Can Razor generate object-oriented code and operate outside the context of a web application? The short answer is yes, but I have done exactly this and I am not sure I would recommend doing it with Razor. I used RazorEngine to generate skeleton models and UI CrUD forms for a set of database tables. I pulled the table schema into an internal object model, did a bit of manipulation on it, and used that as the input model for the template. Here is a simplified example of my Razor template for creating a C# class:

    public partial class @(Model.ObjectName)
    {
        public @(Model.ObjectName) () 
        {
        }
    
        @foreach (UIGen.UITableCol Col in Model.Columns)
        {
    
            if (!Col.IsNullable)
            {
                <text>[System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings=false)]</text>
            }
            if (Col.CSharpType == "string" && Col.MaxLength > 0)
            {
                <text>[StringLength(@Col.MaxLength)]</text>
            }
            @(Col.MVCPropertyAttributes)
            <text>[DisplayName("@(UIGen.Helpers.ToCSharpStringLiteral(Col.ColLabel))")]
                [Column]
                public @Col.CSharpType @Col.ColName { get; set; }
            </text>
        }
    }
    

    It worked for me, but the reasons I wouldn't whole-heartedly recommend it are: