Development good practices - single place for definition of content types

When building a new project with Sitefinity, usually developers brainstorm the customization needed (custom modules, providers, widgets), architecture of the project (Multisite or Multilingual environment), etc. All these steps are essential for the project to be successfully delivered. However what will make your projects even more successful is not only writing working solutions, but a well-structured ones.

The following blog post will demonstrate one good development practice when building a Sitefinity project - keeping all content type names in a string-valued Enum.

No matter if you use built-in content types as Blog posts, Events, News etc. or Dynamic content types (ones created with the Module Builder), you must keep all content type names into a single place. The benefits of this are large - single point of editing, following the DRY principle, easily understanding of all content types that the project uses, etc. The solution is the usage of a string-valued enum. See sample below:

public enum SupportedItemType
{   [StringValue("Telerik.Sitefinity.Blogs.Model.BlogPost")]
    BlogPost = 0,[StringValue("Telerik.Sitefinity.Taxonomies.Model.FlatTaxonomy")]
    FlatTaxonomy = 1,     [StringValue("Telerik.Sitefinity.Taxonomies.Model.HierarchicalTaxonomy")]
    HierarchicalTaxonomy = 2,      [StringValue("Telerik.Sitefinity.DynamicTypes.Model.MyModule.MyType")]
    MyType= 3
}

The code above represents a custom enum named SupportedItemType that contains all content type names needed for the Sitefinity project. In future, you can easily add new types or delete existing ones.

By design, .NET enumerations types do not support string values. To make the solution work, you need to define a custom attribute class with name StringValue. The attribute is constructed with a string and exposes that string via a single Value property. See code below:

public class StringValueAttribute : System.Attribute
{
    private string _value;

    /// <summary>
    /// Initializes a new instance of the <see cref="StringValueAttribute"/> class.
    /// </summary>
    /// <param name="value">The value.</param>
    public StringValueAttribute(string value)
    {
        _value = value;
    }

    /// <summary>
    /// Gets the string value.
    /// </summary>
    /// <value>
    /// The value.
    /// </value>
    public string Value
    {
        get { return _value; }
    }
}

In order to retrieve the string value of an enum, you need to create specific method as shown below:

    /// <summary>
    /// Gets the string value of an enum item.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <returns>The string value</returns>
    public static string GetStringValue(Enum value)
    {
        string output = null;
        Type type = value.GetType();

        //Look for 'StringValueAttribute' 
        //in the field's custom attributes
        FieldInfo fi = type.GetField(value.ToString());
        StringValueAttribute[] attrs =
           fi.GetCustomAttributes(typeof(StringValueAttribute),
                                   false) as StringValueAttribute[];
        if (attrs.Length > 0)
        {
            output = attrs[0].Value;
        }

        return output;
    }

The GetStringValue method is used to get the string value of a specified enumeration. In this case if you pass the following as a parameter to a method:

var contentType = Utilities.GetStringValue(SupportedItemType.BlogPost)

the full type name of Blog posts will be returned:

 "Telerik.Sitefinity.Blogs.Model.BlogPost"
Veronica Milcheva

About Veronica Milcheva

I am a passionate Sitefinity blogger, developer and consultant. In my spare time I enjoy running and listening to music. My personal quote: There's no tough problem, just not enough coffee :)

View Comments

comments powered by Disqus