Creating a Thick Entity Class Template

Templates in Visual Studio are a great way to promote consistency as well as take some of the chore out of common layout when creating items or projects. Creating templates
is easy to do in Visual Studio; you can get started by simply converting existing classes by clicking File > Export Template, and from there follow the wizard. Another option, to gain maximum flexibility, is to create the template by simply using a basic text editor (even Notepad works fine for this).

You can view several pre-existing templates that come pre-built with Visual Studio found in the
ItemTemplate and ProjectTemplate directories (My paths are: C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ItemTemplates
and C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ProjectTemplates,
respectively). The templates are zip files that generally contain three files, your template code (.cs), a template configuration file, and the icon image for the template.

What is a Thick Entity Class?

A thick entity is a class that describes an entity object which also includes, or is at least knowledgeable of business logic as well. A thin entity would be an entity object which only describes the properties of the object (much like an interface) and does not contain methods/functions. There are pro’s and con’s to both which is an entire discussion outside of the scope of this particular article.

The following is a template for creating thick entity classes, or you can download the thick entity class template here and simply copy it to your Visual Studio user template directory (I would place mine here: My Documents\Visual Studio 2008\Templates\ItemTemplates\Visual C#).

ThickEntity.cs

using System;
using System.Collections.Generic;
$if$ ($targetframeworkversion$ == 3.5)using System.Linq;
$endif$using System.Text;

namespace $rootnamespace$
{
    public class $safeitemrootname$
    {
        #region "PROPERTIES"

        /// <summary>
        /// Unique identifier for the $safeitemrootname$.
        /// </summary>
        public int ID { get; set; }

        //TODO: Add additional entity properties

        #endregion

        #region "CONSTRUCTORS"

        /// <summary>
        /// Create an $safeitemrootname$ in memory.
        /// </summary>
        public $safeitemrootname$()
        {
        }

        #endregion

        #region "METHODS"

        /// <summary>
        /// Load existing $safeitemrootname$ from database.
        /// </summary>
        /// <param name="id"></param>
        public void LoadData(int id)
        {
            //TODO: Load from database
        }

	//Add any additional load mechanisms/helpers


        /// <summary>
        /// Save $safeitemrootname$ to database.
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool Save(ref string msg)
        {
            bool result = false;

            //Validate for good input data
            result = ValidateData(ref msg);
            if (result == false)
            {
                return false;
            }

            //Reset result after clears validation
            result = false;

            //Save to database
            try
            {
                if (this.ID > 0)
                {
                    //TODO: Call update function
                }
                else
                {
                    //TODO: Call create function

                    if (this.ID > 0)
                    {
                        result = true;
                    }
                    else
                    {
                        result = false;
                    }
                }
            }
            catch (Exception ex)
            {
                //TODO: Log exception
            }

            if (result == false && string.IsNullOrEmpty(msg))
            {
                //Catch-all generic error
                msg = "An error ocurred while saving.";
            }

            return result;
        }

        /// <summary>
        /// Validate data for $safeitemrootname$.
        /// </summary>
        /// <returns></returns>
        public bool ValidateData()
        {
            string msg = string.Empty;
            bool isValid = ValidateDataHelper(ref msg);
            return isValid;
        }

        /// <summary>
        /// Validate data for $safeitemrootname$.
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public bool ValidateData(ref string msg)
        {
            bool isValid = ValidateDataHelper(ref msg);
            return isValid;
        }

        /// <summary>
        /// Validate data for $safeitemrootname$.
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        private bool ValidateDataHelper(ref string msg)
        {
            StringBuilder sb = new StringBuilder();
            bool isValid = true;

            //TODO: Add validation logic

            if (string.IsNullOrEmpty(sb.ToString()) == false)
            {
                sb.Insert(0, "Oops, some of the data you entered needs attention:");
                msg = sb.ToString();
            }
            else
            {
                msg = string.Empty;
            }

            return isValid;
        }

        #endregion

        #region "STATIC METHODS"

        /// <summary>
        /// Get complete list of $safeitemrootname$s.
        /// </summary>
        /// <returns></returns>
        public static List<$safeitemrootname$> Get$safeitemrootname$s()
        {
            var coll = new List<$safeitemrootname$<();
            
	    //TODO: Load list from data access layer

	    //Example:
	    //var dataColl = $rootnamespace$.DataAccess.Get$safeitemrootname$s();
            //foreach (dataIssue dataItem in dataColl)
            //{
            //    Issue issue = new Issue();
            //    issue.LoadData(linqItem);
            //    coll.Add(issue);
            //}

            return coll;
        }

        #endregion
    }
}

MyTemplate.vstemplate

<VSTemplate Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Item">
  <TemplateData>
    <DefaultName>ThickEntity.cs</DefaultName>
    <Name>ThickEntity</Name>
    <Description>Create a thick (contains business logic) entity class.</Description>
    <ProjectType>CSharp</ProjectType>
    <SortOrder>10</SortOrder>
    <Icon>__TemplateIcon.ico</Icon>
  </TemplateData>
  <TemplateContent>
    <References />
    <ProjectItem SubType="Code" TargetFileName="$fileinputname$.cs" ReplaceParameters="true">ThickEntity.cs</ProjectItem>
  </TemplateContent>
</VSTemplate>

Do you have a collection of useful templates that you would like to share? I would love to share, discuss, and add your templates to my collection. Please contact me or leave code samples directly in the comments.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s