Tuesday, February 21, 2012

Using ReSharper Live Templates to help with Enumerations


While at Codemash this year, a couple of us from our company attended Jimmy Bogard's wicked domain models presentation and were inspired to change how enumerations are modeled within our system.

Why would we want to change to a class from a simple enumeration?

In our API we are trying to minimize the possibility of misuse of enums since a integer can be cast into a enum, this can lead into a number of undesirable issues.

During his talk, Jimmy showed a enumeration as a class with static instances representing the possible values for the enumeration type.  This was a perfect fit as it meant that code could be readable and without the the casting pitfalls of a enum.

For more information on Jimmy's Wicked Domain Models, check out his blog post on enumerations.

http://lostechies.com/jimmybogard/2008/08/12/enumeration-classes/

You can also get the source for the wicked domain models on Jimmy's github project:

https://github.com/jbogard/presentations/tree/master/WickedDomainModels


While implementing a few enumerations we found that we were typing the same code over and over and I looked into how resharper could make the task easier.

What we did with Resharper was to create two live templates.  If you have never used live templates before, they are simply amazing.  They are not dumb static templates, but can have macros that fetch contextual information such as the containing type in our case.

One for the Enumeration class and the other for helping create the static instances.

Enumeration Class Live Template








Enumeration Static Instances




This live template contained three variables, but only two actually are required to be entered by the developer.

The $enumtype$ is set as a macro to fetch the containing type and is defined as Not Editable.

This saves a considerable amount of typing.

The $EnumItemName$ is the name of the enumeration item and only the first instance in the template is editable.

The $value$ is the numeric value to the enumeration item.

Here is a screen shot of the settings for the live template parameter settings.



An example implementation of a enumeration.


    // Sample Implementation, see Jimmy Bogards Wicked Domain model for a more
    // complete implementation.
 
    public abstract class Enumeration
    {
        private readonly int _value;
        private readonly string _displayName;
 
        protected Enumeration()
        {
        }
 
        protected Enumeration(int value, string displayName)
        {
            _value = value;
            _displayName = displayName;
        }
 
        public int Value
        {
            get { return _value; }
        }
 
        public string DisplayName
        {
            get { return _displayName; }
        }
 
        public override string ToString()
        {
            return DisplayName;
        }
    }
 
    public class CarEnum : Enumeration
    {
 
        public static readonly CarEnum Chevrolet = new CarEnum(1, "Chevrolet");
        public static readonly CarEnum Ferari = new CarEnum(2, "Ferari");
        public static readonly CarEnum Volkswagen = new CarEnum(3, "Volkswagen");
        
        private CarEnum(int value, string displayName) : base(value, displayName)
        {
        }
 
    }
 
    public class EnumerationTest
    {
        public void TestCars()
        {
 
            CarEnum chevy = CarEnum.Chevrolet;
 
            CarEnum car = chevy;
 
            if (car == CarEnum.Chevrolet)
            {
                
            }
 
        }
    }


Hopefully this information helps others take advantage of reshaper's live templates.