Interfaz fluida para renderizar HTML

Renderizar HTML con HtmlTextWriter no es increíblemente intuitivo en mi opinión, pero si está implementando controles web en formularios web, es con lo que tiene que trabajar. Pensé que podría ser posible crear una interfaz fluida para esto que se lea un poco más como el HTML que genera. Me gustaría saber qué piensa la gente de la sintaxis que se me ocurrió hasta ahora.

    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" y "EndTag" son métodos de extensión para la clase HtmlTextWriter que devuelve la instancia que se necesita para que las llamadas se puedan encadenar. El argumento pasado a la lambda utilizada en la sobrecarga utilizada por la primera llamada a "Tag" es un "HtmlAttributeManager", que es una clase simple que envuelve un HtmlTextWriter para proporcionar un indexador que toma un HtmlTextWriterAttribute y un valor de cadena y devuelve la instancia. que las llamadas se pueden encadenar También tengo métodos en esta clase para los atributos más comunes, como "Nombre", "Clase" e "Id" para que pueda escribir la primera llamada de la siguiente manera:

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

Un pequeño ejemplo más largo:

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);
}

Esperemos que pueda "descifrar" qué HTML genera este fragmento, al menos esa es la idea.

Por favor, piense en cómo se puede mejorar la sintaxis, tal vez mejores nombres de métodos, tal vez algún otro enfoque en conjunto.

Editar: pensé que podría ser interesante ver cómo se vería el mismo fragmento sin el uso de la interfaz fluida, para comparar:

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();
}

EDITAR: Probablemente debería ser un poco más explícito en que uno de los objetivos con esto es que debe incurrir en la menor sobrecarga posible, es por eso que he limitado el uso de lambdas. También al principio usé una clase que representaba una etiqueta para que la sintaxis construyera algo similar a un árbol DOM antes de la representación, aunque la sintaxis era muy similar. Abandoné esta solución por la leve sobrecarga de memoria en la que incurre. Todavía hay algo de esto presente en el uso de la clase HtmlAttributeManager, he estado pensando en usar métodos de extensión para agregar atributos también, pero no puedo usar la sintaxis indexadora, también hincha la interfaz de HtmlTextWriter aún más.

Respuestas a la pregunta(4)

Su respuesta a la pregunta