Geeks With Blogs
Pounding Code technological rantings and code samples

This is the first in a several part posting about T4-Toolbox. More to follow

You landed here because you're interested in code generation, working faster, generating uniform code, forestalling corpal tunnel syndrome, etc. But perhaps, you need convincing it's worth the effort 

What's the difference between this class:
    public partial class Evaluation : KeyedObject
    {
        public virtual string Description { get; set; }
        public virtual Guid EvaluationTypeId { get; set; }
        public virtual decimal Bias { get; set; }
        public virtual decimal Correlation { get; set; }
        public virtual decimal Version { get; set; }
        public virtual decimal Release { get; set; }
        public virtual EvaluationType EvaluationType { get; set; }
        public virtual LazyList<ParticipantEvaluation> ParticipantEvaluations { get; set; }
    }

and this class:
    public partial class Evaluation : KeyedObject
    {
        [DisplayName("Description")]
        [Required(ErrorMessage ="Description is required")]
        [StringLength(500, ErrorMessage ="Description max length is 500" )]
        public virtual string Description { get; set; }

        [DisplayName("Evaluation Type")]
        [Required(ErrorMessage ="Evaluation Type is required")]
        public virtual System.Guid EvaluationTypeId { get; set; }
  
        [DisplayName("Bias")]
        [Required(ErrorMessage ="Bias is required")]
        public virtual decimal Bias { get; set; }
   
        [DisplayName("Correlation")]
        [Required(ErrorMessage ="Correlation is required")]
        public virtual decimal Correlation { get; set; }
   
        [DisplayName("Version")]
        [Required(ErrorMessage ="Version is required")]
        public virtual decimal Version { get; set; }
   
        [DisplayName("Release")]
        [Required(ErrorMessage ="Release is required")]
        public virtual decimal Release { get; set; }
       [DisplayName("Evaluation Type")]
        public virtual EvaluationType EvaluationType { get; set;}
        [DisplayName("Participant Evaluations")]
        public virtual LazyList<ParticipantEvaluation> ParticipantEvaluations { get; set;}
}


On the surface you can see that both are describing the same domain object, and that one version has implemented DataAnnotations. What you can't see here is that one of these classes was generated dynamically and in virtually under a second using the T4 Toolbox.  I know that may not seem all that exciting, even if you've already guessed that it was the version that has the DataAnnotations is the one generated from the template.


Let's look at something a bit more complex.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Survey.Core.Domain.Model;

namespace Survey.Core.Domain
{
    public class EvaluationRepository : IEvaluationRepository
    {

        private Survey.Core.Repository.SqlDataContext _context = new Survey.Core.Repository.SqlDataContext();

        public EvaluationRepository() { }

        public EvaluationRepository(Survey.Core.Repository.SqlDataContext context)
        {
            _context = context;
        }
       

        public IQueryable<Evaluation> GetIQueryableCollection()
        {
            ICriterionRepository criteriaRep = new CriterionRepository(_context);
            return from entity in _context.Evaluations
                   let criteria = criteriaRep.GetIQueryableCollection().Where(x => x.EvaluationId == entity.Id)
                   select new Evaluation()
                   {  
                    Code = entity.Code,
                    Description = entity.Description,                   
                    Id = entity.Id ,
                    EvaluationTypeId = entity.EvaluationTypeId,
                    IsEditable = entity.IsEditable,
                    Release = entity.Release,
                    ReplacesEvaluationId = entity.ReplacesEvaluationId,
                    Version = entity.Version,
                    Criteria = new LazyList<Criterion>(criteria),
                    EvaluationType = new EvaluationType{ Id= entity.EvaluationType.Id, Code=entity.EvaluationType.Code},
                    ModifiedDate = entity.ModifiedDate,
                    ModifiedBy = entity.ModifiedBy,
                   
                   };
        }
       

        public void Save(Evaluation model)
        {
            if (model != null)
            {
                Survey.Core.Repository.SqlDataContext dataCtx = new Survey.Core.Repository.SqlDataContext();
                using (dataCtx)
                {
                    Survey.Core.Repository.Evaluation entity;
                    try
                    {
                        entity = (from e in dataCtx.Evaluations
                                  where e.Id == model.Id
                                  select e).SingleOrDefault() ?? new Survey.Core.Repository.Evaluation();
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                    //// synch it
                    entity = Sync(entity, model);

                    if (entity.Id == Guid.Empty)
                        dataCtx.Evaluations.InsertOnSubmit(entity);
                    try
                    {
                        dataCtx.SubmitChanges();
                        model.Id = entity.Id;
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
            }
        }

        public void Delete(Evaluation evaluation)
        {
            throw new NotImplementedException();
        }

        public Evaluation[] GetAll()
        {
            Evaluation[] list = GetIQueryableCollection().ToArray<Evaluation>();
            return list;
        }

        public Evaluation GetById(Guid id)
        {
            return GetIQueryableCollection().Where(x => x.Id == id).FirstOrDefault();
        }
       
        public Evaluation GetByKey(string key)
        {
            return GetIQueryableCollection().Where(x => x.Code == key).FirstOrDefault();
        }

        static private Repository.Evaluation Sync(Survey.Core.Repository.Evaluation entity, Evaluation model)
        {
            entity.Code = model.Code;
            entity.Description = model.Description;
            entity.EvaluationTypeId = model.EvaluationTypeId;
            entity.IsEditable = model.IsEditable;
            entity.ModifiedBy = model.ModifiedBy;           
            entity.ModifiedDate = DateTime.Now;
            entity.Release = model.Release;
            entity.ReplacesEvaluationId = model.ReplacesEvaluationId;
            entity.Version = model.Version;
            return entity;
        }
    }
}
 

As compared to:
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Survey.Core;
using Survey.Core.Domain.Model;

namespace Survey.Core.Domain.Model
{

     public interface IEvaluationRepository : IKeyedRepository<Evaluation>
    {
        new void Save(Evaluation entity);
        new void  Delete(Evaluation entity);
        new Evaluation[] GetAll();
        new Evaluation GetById(Guid id);
        IQueryable<Evaluation> GetIQueryableCollection();
        Survey.Core.Repository.MetrixContext  GetDataContext();
    }
 
    public class EvaluationRepository : IEvaluationRepository
    {
        private Survey.Core.Repository.MetrixContext _context = new  Survey.Core.Repository.MetrixContext();
       
        public EvaluationRepository (){}
       
        public EvaluationRepository(Survey.Core.Repository.MetrixContext context)
        {
            _context = context;
        }
       
        public  IQueryable<Evaluation> GetIQueryableCollection()
        {
            return from entity in _context.Evaluations
               select new Evaluation()
               {
                    Id = entity.Id,
                    Key = entity.Key,
                    EvaluationTypeId = entity.EvaluationTypeId,
                    Description = entity.Description,
                    Bias = entity.Bias,
                    Correlation = entity.Correlation,
                    Version = entity.Version,
                    Release = entity.Release,
                    IsEditable = entity.IsEditable,
                    ReplacesEvaluationId = entity.ReplacesEvaluationId,
                    Elaboration = entity.Elaboration,
                    ModifiedDate = entity.ModifiedDate,
                    ModifiedBy = entity.ModifiedBy,
                 };   
         }
       
        public void Save(Evaluation model)
        {
            if (model != null)
            {
                Survey.Core.Repository.MetrixContext dataCtx = new Survey.Core.Repository.MetrixContext();
                using (dataCtx)
                {
                    Survey.Core.Repository.Evaluation entity;
       
                    entity = (from e in dataCtx.Evaluations
                              where e.Id == model.Id
                              select e).SingleOrDefault() ?? new Survey.Core.Repository.Evaluation();
       
                    //// synch it
                    entity = Sync(entity, model);
       
                    if (entity.Id == Guid.Empty)
                        dataCtx.Evaluations.InsertOnSubmit(entity);
                    try
                    {
                        dataCtx.SubmitChanges();
                        model.Id = entity.Id;
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
            }
        }
        public void Delete(Evaluation model)
        {
            if (model != null)
                {
                    Survey.Core.Repository.MetrixContext dataCtx = new Survey.Core.Repository.MetrixContext(); // we create a separate data context for saves, as they are disposed after the insert.
                    using (dataCtx)
                    {
                         Survey.Core.Repository.Evaluation entity;
                        try
                        {
                            if (model.Id != Guid.Empty)
                            {
                                entity = (from e in dataCtx.Evaluations
                                             where e.Id == model.Id
                                             select e).SingleOrDefault();
                                if (entity != null)
                                {
                                    dataCtx.Evaluations.DeleteOnSubmit(entity);
                                    dataCtx.SubmitChanges();
                                }
                            }
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                    }
                }
        }
        public Evaluation[] GetAll()
        {
            return GetIQueryableCollection().ToArray<Evaluation>();
        }
       
        public Evaluation GetById(Guid id)
        {
            return GetIQueryableCollection().Where(x => x.Id == id).FirstOrDefault();
        }
       
        public Evaluation GetByKey(string key)
        {
            return GetIQueryableCollection().Where(x => x.Key == key).FirstOrDefault();
        }
         
        public  Survey.Core.Repository.Evaluation Sync(Survey.Core.Repository.Evaluation entity, Evaluation model)
        {
                entity.Id = model.Id;
                entity.Key = model.Key;
                entity.EvaluationTypeId = model.EvaluationTypeId;
                entity.Description = model.Description;
                entity.Bias = model.Bias;
                entity.Correlation = model.Correlation;
                entity.Version = model.Version;
                entity.Release = model.Release;
                entity.IsEditable = model.IsEditable;
                entity.ReplacesEvaluationId = model.ReplacesEvaluationId;
                entity.Elaboration = model.Elaboration;
                entity.ModifiedDate = model.ModifiedDate;
                entity.ModifiedBy = model.ModifiedBy;
            return entity;
        }
       
        public Survey.Core.Repository.MetrixContext GetDataContext()
        {
             return _context;
        }
    }
}

One was crafted by hand, the second drawn from a template. If you look close enough, you'll be able to tell which one was hand coded because it's the one that contains an unimplemented excpetion!  This is what excites me about code generation: the ability to build the software you want to build in less time.  In this article I'm going to show you how I leveraged the open source T4 Toolbox to build out complex project files. 
 

The code for this project is now up on codeplex http://t4tarantino.codeplex.com/
 

Posted on Wednesday, August 18, 2010 9:59 PM T4 | Back to top

Related Posts on Geeks With Blogs Matching Categories

Comments on this post: Code Generation with T4 toolbox Part 1: The elevator pitch

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © James Fleming | Powered by: GeeksWithBlogs.net