HiveBrain v1.2.0
Get Started
← Back to all entries
principlecsharpMinor

C# Multi level HTML TagBuilder object - Design pattern Review needed

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
neededmultitagbuilderleveldesignpatternobjectreviewhtml

Problem

I find the TagBuilder written in C# little poor without the ability to "host" inside it sub tags (as objects not as strings).

So I wrote a simple class that inherits TagBuilder and allow to save sub tags.
I can navigate inside it and add things to it while I move across the application.
And when I call the Top Tag Object .ToString, it will render the entire html

public class MultiLevelHtmlTag : TagBuilder
{
    public MultiLevelHtmlTag(string tagName) : base(tagName) { }

    public List InnerTags = new List();

    public override string ToString()
    {
        if (InnerTags.Count > 0)
        {
            foreach (MultiLevelHtmlTag tag in InnerTags)
            {
                this.InnerHtml += tag.ToString();
            }
        }
        return base.ToString();
    }
}


this is how I use it:

MultiLevelHtmlTag top = new MultiLevelHtmlTag("div");
top.InnerTags.Add(new MultiLevelHtmlTag("span"));
log.Debug(top.ToString());


output:



What do you think about it?
is that a goot pattern?

Solution

I would make sure the list is not exposed publicly - the caller can then do whatever they want with that list, even assign null to it. So I've refactored it a little bit and implemented Add() (you may also want to implement Remove(), etc.):

/// 
/// Simple class that inherits TagBuilder and allow to save sub tags.
/// 
public class MultiLevelHtmlTag : TagBuilder
{
    /// 
    /// List of inner tags.
    /// 
    private readonly IList innerTags = new List();

    /// 
    /// Initializes a new instance of the  class.
    /// 
    /// The name of the tag.
    public MultiLevelHtmlTag(string tagName) : base(tagName)
    {
    }

    /// 
    /// Gets the inner tag list.
    /// 
    /// The inner tag list.
    public IEnumerable InnerTags
    {
        get
        {
            return new ReadOnlyCollection(this.innerTags);
        }
    }

    /// 
    /// Adds the specified tag to the inner tag list.
    /// 
    /// The tag to add.
    public void Add(MultiLevelHtmlTag tag)
    {
        if (tag == null)
        {
            throw new ArgumentNullException("tag");
        }

        this.innerTags.Add(tag);
    }

    /// 
    /// Returns a  that represents this instance.
    /// 
    /// 
    /// A  that represents this instance.
    /// 
    public override string ToString()
    {
        var sb = new StringBuilder();

        foreach (var tag in this.innerTags)
        {
            sb.Append(tag.ToString());
        }

        this.InnerHtml = sb.ToString();
        return base.ToString();
    }
}

Code Snippets

/// <summary>
/// Simple class that inherits TagBuilder and allow to save sub tags.
/// </summary>
public class MultiLevelHtmlTag : TagBuilder
{
    /// <summary>
    /// List of inner tags.
    /// </summary>
    private readonly IList<MultiLevelHtmlTag> innerTags = new List<MultiLevelHtmlTag>();

    /// <summary>
    /// Initializes a new instance of the <see cref="MultiLevelHtmlTag"/> class.
    /// </summary>
    /// <param name="tagName">The name of the tag.</param>
    public MultiLevelHtmlTag(string tagName) : base(tagName)
    {
    }

    /// <summary>
    /// Gets the inner tag list.
    /// </summary>
    /// <value>The inner tag list.</value>
    public IEnumerable<MultiLevelHtmlTag> InnerTags
    {
        get
        {
            return new ReadOnlyCollection<MultiLevelHtmlTag>(this.innerTags);
        }
    }

    /// <summary>
    /// Adds the specified tag to the inner tag list.
    /// </summary>
    /// <param name="tag">The tag to add.</param>
    public void Add(MultiLevelHtmlTag tag)
    {
        if (tag == null)
        {
            throw new ArgumentNullException("tag");
        }

        this.innerTags.Add(tag);
    }

    /// <summary>
    /// Returns a <see cref="System.String"/> that represents this instance.
    /// </summary>
    /// <returns>
    /// A <see cref="System.String"/> that represents this instance.
    /// </returns>
    public override string ToString()
    {
        var sb = new StringBuilder();

        foreach (var tag in this.innerTags)
        {
            sb.Append(tag.ToString());
        }

        this.InnerHtml = sb.ToString();
        return base.ToString();
    }
}

Context

StackExchange Code Review Q#5526, answer score: 6

Revisions (0)

No revisions yet.