Rapid Application Development with Code Generators

What if I would tell you that you can potentially shorten the development time of (some) enterprise-class software from months to weeks? What if I would tell you can generate software only by describing your business model in the form of simple classes and attributes? If you are a developer, you may be a little scared now. Does it mean the world does not really need so many of us to build products? While this may not be the case just yet – unfortunately, I think eventually we will find get to a point where we can build quicker with less actual code being written) but I’ll let you draw your own conclusions of where the technology is going and as always please feel free to leave a comment.

While I agree you cannot really automate software engineering 100% (some customers problems need very custom solutions – not something you can just generate). I think a large part of our work is very repetitive. Think about all the code you have to configure just to make a basic application running: create-update-delete functionality for all those domain objects, authentication, authorization, reliable database access, UI Framework configuration, Routing, Services orchestration, error handling, localisation and globalization, grids, search forms and let’s not forget about minification, bundling etc. Occasionally, you will also need to add support for multi-tenancy. That’s a lot of work and most of all, a lot of potential for bugs and rework, not to mention the later maintenance cost of all this boilerplate code.

To help you with these problems come code generators. There are many available out there for different purposes and different languages but here I will focus on Serenity which is a .Net Core / C# / Typescript code generator. If you come from Java background I can recommend  jHipster which is based on Yeoman. While JHipster allows you to quickly scaffold Spring Boot + Angular/React + Micro services application, it is only a plugin for Yeoman which allows scaffolding all sorts of applications including .Net, Python, iOS and many more via its generators which are all neatly listed here.

 Let me start with describing briefly what Serenity can do and how little manual work is required from you. First of all, you have to describe your data model in the form of a relational database. You will have to follow some conventions so that when you run Serenity code generator, it will be able to understand your model and correctly interpret all the relations. It is recommended but not required that you use FluentMigrations which will allow you to describe your db schema using C# code. FluentMigrator code required to create a table could look similar to this:

[Migration(20180519115100)]
public class DefaultDB_20180519_115100_MovieTable : Migration
{
    public override void Up()
    {
        Create.Schema("mov");

        Create.Table("Movie").InSchema("mov")
            .WithColumn("MovieId").AsInt32()
                .Identity().PrimaryKey().NotNullable()
            .WithColumn("Title").AsString(200).NotNullable()
            .WithColumn("Description").AsString(1000).Nullable()
            .WithColumn("Storyline").AsString(Int32.MaxValue).Nullable()
            .WithColumn("Year").AsInt32().Nullable()
            .WithColumn("ReleaseDate").AsDateTime().Nullable()
            .WithColumn("Runtime").AsInt32().Nullable();    
    }

    public override void Down()
    {
    }
}

Once you have created your schema, you need to run an executable called Sergen.exe which is a simple app that needs only a connection string from you. Once it reads your db schema, it will do its templating magic and create a CRUD application for all your entities. The scaffolded functionality will include among others:
• UI with a search and navigation capabilities
• Data entry and editing forms including basic validation
• The database itself (if you went with the Fluent Migrator route)
• Repository classes encapsulating basic CRUD and search functionality
• Service classes which utilise repositories (you can customize your business logic here if needed)
• Typescript code describing client-side forms and widgets
Visually, the generated application could resemble something similar to this:

 

I would say that’s pretty impressive for something that took an hour of work (that’s how long it took me to follow the tutorial). Obviously, it will take longer to customize and properly describe your domain model for Serenity but it would take much, much more time if you have decided to do it all manually.
Code wise Sergen will create an xxxRow classes describing database entities and xxxForm classes describing UI Representation of our entities. Sergen will use the xxxForms classes to generate corresponding typescript code. An example of one of the forms from tutorial looks like this:

namespace MovieTutorial.MovieDB.Forms
{
    //...
    [FormScript("MovieDB.Movie")]
    [BasedOnRow(typeof(Entities.MovieRow))]
    public class MovieForm
    {
        public String Title { get; set; }
        public String Description { get; set; }
        public String Storyline { get; set; }
        public Int32 Year { get; set; }
        public DateTime ReleaseDate { get; set; }
        public Int32 Runtime { get; set; }
    }
}

And the corresponding UI form will result in this:

Note that we already have grids supporting paging and quick search available to us! We can customize everything we see here by either adding custom code or decorating our models with appropriate well-documented attributes. For example, we can make a field displaying a filename of an image into a component displaying that image and allowing to upload new ones just by decorating the said property with the ImageUploadEditor attribute:

        [DisplayName("Gallery Images"),
        MultipleImageUploadEditor(FilenameFormat = "Movie/GalleryImages/~")]
        public string GalleryImages
        {
            get { return Fields.GalleryImages[this]; }
            set { Fields.GalleryImages[this] = value; }
        }

We could add a quick search capabilities to a form simply by adding a QuickSearch attribute:

[DisplayName("Title"), Size(200), NotNull, QuickSearch(SearchType.StartsWith)]
public String Title
{
    get { return Fields.Title[this]; }
    set { Fields.Title[this] = value; }
}

So, as you can see we can fairly quickly set up a working CRUD type applications, that’s useful for any administrative interfaces or applications with many data entry forms. You can use it as a base for more complex applications as Serenity is easily extendable on any level and it’s also open source so you can even extend the generator itself if needed. And once again, if you need anything else you are not limited to Serenity. Remember that there are many code generators of various flavours. Have a look here where you can either use one of many community generators or build one yourself if you often find yourself building similar applications (think: software house scenarios).

Lastly, remember that code generators are just another tool, you may not need it now, but it sure is good to be aware that such tools exist in case you ever need them.