Sunday, November 10, 2013

Simple T4 Template to create knockout.js models for an Entity Framework Code First DbContext

At work I use a healthy combo of EF Code First, Asp.Net Web Api, and Knockout.  This combo is really nice for quickly creating crud apps.  Unfortunately, I find myself recreating my entities from the C# in javascript.
"Don't write the same code twice." - Advice from every code book ever.

C# model !== Javascript model, but close enough for me.

This brings me to a small project for today, create a t4 template in Visual Studio to transform the entities exposed by my DbContext into Knockout based Javascript models.

T4 Template source on GitHub



Basic DbContext with POCOs
namespace T4Templates.Entities {
    public class MyDataContext:DbContext {
        public DbSet People { get; set; }
        public DbSet Projects { get; set; }
        public DbSet Vendors { get; set; }
    }
    public class Person {
        public Guid PersonKey { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
    public class Project {
        public Guid ProjectKey { get; set; }
        public Guid Name { get; set; }
        public IEnumerable Vendors { get; set; }
    }
    public class Vendor {
        public Guid VendorKey { get; set; }
        public Guid Name { get; set; }
    }
}
Results from transform.
(function () {
    var nameSpace = 'MyNameSpaceHere';
    var ns = {};
    ns.Models = {
        Person: function (data) {
            this.PersonKey = ko.observable();

            this.FirstName = ko.observable();

            this.LastName = ko.observable();

            this.update = function (data) {
                ko.mapping.fromJS(data, {}, this);
            }
            if (data != undefined) {
                this.update(data);
            }
        },

        Project: function (data) {
            this.ProjectKey = ko.observable();

            this.Name = ko.observable();

            this.Vendors = ko.observableArray();
            this.update = function (data) {
                ko.mapping.fromJS(data, {}, this);
            }
            if (data != undefined) {
                this.update(data);
            }
        },

        Vendor: function (data) {
            this.VendorKey = ko.observable();

            this.Name = ko.observable();

            this.update = function (data) {
                ko.mapping.fromJS(data, {}, this);
            }
            if (data != undefined) {
                this.update(data);
            }
        },

    }
    window[nameSpace] = ns || {};
})();

T4 Template source on GitHub

No comments:

Post a Comment