Executando verificação de segurança...
4

HtmlMail.TemplateEngine 📧 - Biblioteca que simplifica a criação de body de email usando .NET

📌 Problema que eu queria resolver:

Escrever HTML dentro do código C# é um sofrimento.

Quem já precisou gerar corpo de e-mail ou qualquer HTML dinâmico sabe como é:

  • Strings quebradas e longas em arquivos C#
  • Difícil de dar manutenção
  • Testar? Só enviando o email rs 😂

💡 Minha solução:

Uma template engine leve, sem dependências pesadas, que permite:

✅ Escrever o HTML puro, com marcações tipo Razor (@Model.Prop, @{ if (...) { ... } })
✅ Passar um objeto C# (model) e pronto:
✅ Gerar o HTML final de forma simples


✅ Exemplo de template HTML (Ex: template.html):


<style></style>

<p>Olá @Model.Nome</p>

@{
    if (Model.Idade > 18)
    {
        sb.Append("<p>Maior de idade!</p>");
    }
}

✅ Exemplo de template CSS (Ex: style.css):


* {
  background-color: red;
  }

✅ Como chamar no C#:

string html = await Template.GenerateHtml("/your/path/template.html", "/your/path/style.css", model);

Parâmetros:

ParâmetroDescrição
/your/path/template.htmlCaminho para o arquivo HTML com as marcações
/your/path/style.cssCaminho para um arquivo CSS que será embutido automaticamente dentro de <style></style>
modelObjeto com os dados que o template vai usar

✅ O que ele suporta?

  • Blocos de código com @{ ... }
  • Expressões inline com @Model.Propriedade, @{Model.Valor * 2}, etc
  • Multiplas linhas de código dentro do template
  • Uso de lógica condicional (if, loops, etc)
  • Importação automática do namespace do tipo do model

🚀 Como instalar:

dotnet add package HtmlMail.TemplateEngine

✅ Tecnologias usadas:

  • .NET 8+
  • Roslyn Scripting API (Microsoft.CodeAnalysis.CSharp.Scripting)

✅ Por que criei isso?

Eu queria:

  • Fugir de Razor pesado.
  • Fugir de escrever html em arquivo C#, usar o autocomplete do HTML e CSS ao maximo.
  • Algo rápido só pra geração de HTML de emails, relatórios ou qualquer conteúdo pequeno.

👉 https://github.com/Isaias-Vasconcelos/html-template-mail


✅ Exemplo de uso completo:

Template HTML (arquivo físico):


<style></style>

<h1>Pedido confirmado!</h1>
<p>Cliente: @Model.Cliente</p>

@{
    foreach(var item in Model.Itens)
    {
        sb.Append($"<p>Produto: {item}</p>");
    }
}

<p>Obrigado por comprar conosco!</p>

Código C#:

using HtmlMail;

public class Pedido
{
    public string Cliente { get; set; }
    public List<string> Itens { get; set; }
}

// Exemplo de uso:
var pedido = new Pedido
{
    Cliente = "João da Silva",
    Itens = new List<string> { "Camisa", "Calça", "Tênis" }
};

string html = await Template.GenerateHtml("/your/path/pedido.html", "/your/path/estilo.css", pedido);

Saída:


<style>

* {
  background-color:red;
  }
</style>

<h1>Pedido confirmado!</h1>
<p>Cliente: João da Silva</p>

<p>Produto: Camisa</p><p>Produto: Calça</p><p>Produto: Tênis</p>

<p>Obrigado por comprar conosco!</p>

✅ Quer contribuir?

PRs e sugestões são bem-vindas! 😄


✅ Dúvidas?

Pode abrir uma issue no GitHub

✅ Licença:

MIT License.


Feito por Isaias Vasconcelos 🧑‍💻

Carregando publicação patrocinada...
2

É legal a ideia, mas seu código parece bastante perigoso e lento. Você invoca código durante o runtime. Para isso, tem que compilar e executar o código, que já é um tempo gigantesco. É a mesma ideia do RazorLight.

O perigo está na execução de código malicioso em um ambiente que você não tem total controle dos arquivos "template" que serão usados.

Para contornar o tempo de espera toda vez que for compilar um script do template, você pode fazer o template expor um método que irá compilar o template e compilar uma vez só, depois de chamar o CSharpScript.EvaluateAsync, o método já estará disponível no seu AppDomain, então poderá invocá-lo através de reflexão, sem exigir outra compilação.

Você precisará gerar uma namespace para cada script gerado também, é claro.

Uma alternativa ainda mais segura é usar source generators, que é uma ferramenta avançada, mas super performática.

Eu venho há algum tempo cuidando de um gerador de HTML que criei usando C#. O foco dele é ser super simples, minimalista, fácil de usar. Algo como:

string[] Products = ["Camisa", "Calça", "Tênis"];
string Cliente = "João da Silva";

HtmlElement body = HtmlElement.Fragment(
    HtmlElement.Auto("style", """
        * {
            background-color: red;
        }
        """),
    HtmlElement.Auto("h1", "Pedido confirmado!"),
    HtmlElement.Auto("p", "Cliente: ",
        HtmlElement.Auto("strong", Cliente)),
    HtmlElement.Auto("p", "Você comprou os produtos:"),
    HtmlElement.Auto("ul",
        Products.Select(p => HtmlElement.Auto("li", p))),
    HtmlElement.Auto("p", "Obrigado por comprar conosco!"));

Gera este resultado:

<style>
    * {
        background-color: red;
    }
</style>
<h1>Pedido confirmado!</h1>
<p>Cliente: <strong>João da Silva</strong></p>
<p>Você comprou os produtos:</p>
<ul>
    <li>Camisa</li>
    <li>Calça</li>
    <li>Tênis</li>
</ul>
<p>Obrigado por comprar conosco!</p>

Em só alguns ciclos de processamento.

1

Excelente ponto! Foi algo que já estava observando enquanto eu analisava o tempo de execução. O grande obstáculo que enfrento é quanto a leitura de um arquivo .html, as instruções C# estão nele, sigo na luta para deixar isso cada vez mais leve e rápido para o processador. Dei uma olhada na sua, e confesso, está ficando incrível!

Com seu feedback já consigo pensar nas próximas melhorias!

Agradeço sua colocação!