Interface fluente para renderizar HTML

Renderizar HTML com o HtmlTextWriter não é incrivelmente intuitivo na minha opinião, mas se você estiver implementando controles da Web em formulários da Web, é com isso que você deve trabalhar. Eu pensei que seria possível criar uma interface fluente para isso, que se pareça um pouco mais com o HTML que ele gera. Eu gostaria de saber o que as pessoas pensam da sintaxe que eu criei até agora.

    public void Render(HtmlTextWriter writer)
    {
        writer
            .Tag(HtmlTextWriterTag.Div, e => e[HtmlTextWriterAttribute.Id, "id"][HtmlTextWriterAttribute.Name,"name"][HtmlTextWriterAttribute.Class,"class"])
                .Tag(HtmlTextWriterTag.Span)
                    .Text("Lorem")
                .EndTag()
                .Tag(HtmlTextWriterTag.Span)
                    .Text("ipsum")
                .EndTag()
            .EndTag();        
    }

"Tag", "Text" e "EndTag" são métodos de extensão para a classe HtmlTextWriter que retorna a instância utilizada para que as chamadas possam ser encadeadas. O argumento passado para o lambda usado na sobrecarga usada pela primeira chamada para "Tag" é um "HtmlAttributeManager", que é uma classe simples que envolve um HtmlTextWriter para fornecer um indexador que usa um HtmlTextWriterAttribute e um valor de string e retorna a instância para que as chamadas podem ser encadeadas. Também tenho métodos nessa classe para os atributos mais comuns, como "Nome", "Classe" e "Id", para que você possa escrever a primeira chamada acima da seguinte maneira:

.Tag(HtmlTextWriterTag.Div, e => e.Id("id").Name("name").Class("class"))

Um exemplo mais longo:

public void Render(HtmlTextWriter writer)
{
    writer
        .Tag(HtmlTextWriterTag.Div, a => a.Class("someClass", "someOtherClass"))
            .Tag(HtmlTextWriterTag.H1).Text("Lorem").EndTag()
            .Tag(HtmlTextWriterTag.Select, t => t.Id("fooSelect").Name("fooSelect").Class("selectClass"))
                .Tag(HtmlTextWriterTag.Option, t => t[HtmlTextWriterAttribute.Value, "1"][HtmlTextWriterAttribute.Title, "Selects the number 1."])
                    .Text("1")
                .EndTag(HtmlTextWriterTag.Option)
                .Tag(HtmlTextWriterTag.Option, t => t[HtmlTextWriterAttribute.Value, "2"][HtmlTextWriterAttribute.Title, "Selects the number 2."])
                    .Text("2")
                .EndTag(HtmlTextWriterTag.Option)
                .Tag(HtmlTextWriterTag.Option, t => t[HtmlTextWriterAttribute.Value, "3"][HtmlTextWriterAttribute.Title, "Selects the number 3."])
                    .Text("3")
                .EndTag(HtmlTextWriterTag.Option)
            .EndTag(HtmlTextWriterTag.Select)
        .EndTag(HtmlTextWriterTag.Div);
}

Espero que você consiga "decifrar" qual HTML esse snippet gera, pelo menos essa é a ideia.

Por favor, pense sobre como a sintaxe pode ser aprimorada, talvez melhores nomes de métodos, talvez alguma outra abordagem.

Edit: Eu pensei que poderia ser interessante ver como seria o mesmo snippet sem o uso da interface fluente, para comparação:

public void RenderUsingHtmlTextWriterStandardMethods(HtmlTextWriter writer)
{
    writer.AddAttribute(HtmlTextWriterAttribute.Class, "someClass someOtherClass");
    writer.RenderBeginTag(HtmlTextWriterTag.Div);

    writer.RenderBeginTag(HtmlTextWriterTag.H1);
    writer.Write("Lorem");
    writer.RenderEndTag();

    writer.AddAttribute(HtmlTextWriterAttribute.Id, "fooSelect");
    writer.AddAttribute(HtmlTextWriterAttribute.Name, "fooSelect");
    writer.AddAttribute(HtmlTextWriterAttribute.Class, "selectClass");
    writer.RenderBeginTag(HtmlTextWriterTag.Select);

    writer.AddAttribute(HtmlTextWriterAttribute.Value, "1");
    writer.AddAttribute(HtmlTextWriterAttribute.Title, "Selects the number 1.");
    writer.RenderBeginTag(HtmlTextWriterTag.Option);
    writer.Write("1");
    writer.RenderEndTag();

    writer.AddAttribute(HtmlTextWriterAttribute.Value, "2");
    writer.AddAttribute(HtmlTextWriterAttribute.Title, "Selects the number 2.");
    writer.RenderBeginTag(HtmlTextWriterTag.Option);
    writer.Write("2");
    writer.RenderEndTag();

    writer.AddAttribute(HtmlTextWriterAttribute.Value, "3");
    writer.AddAttribute(HtmlTextWriterAttribute.Title, "Selects the number 3.");
    writer.RenderBeginTag(HtmlTextWriterTag.Option);
    writer.Write("3");
    writer.RenderEndTag();

    writer.RenderEndTag();

    writer.RenderEndTag();
}

Edição: Eu provavelmente deveria ser um pouco mais explícito em que um dos objetivos com isso é que isso acarreta o mínimo de sobrecarga possível, é por isso que limitei o uso de lambdas. Também no começo eu usei uma classe que representava uma tag para que algo semelhante a uma árvore DOM fosse construído pela sintaxe antes da renderização, mas a sintaxe era muito semelhante. Abandonei esta solução pela leve sobrecarga de memória em que ela incorre. Ainda há um pouco disso presente no uso da classe HtmlAttributeManager. Também estive pensando em usar métodos de extensão para anexar atributos, mas não consigo usar a sintaxe do indexador, mas também incha a interface do HtmlTextWriter ainda mais.

questionAnswers(4)

yourAnswerToTheQuestion