Building an email body So here we are, using a StringBuilder to build an email body. I know there's a lot on StackOverflow and endless debate/discussion around how best to concatenate strings.


Can this be done in fewer lines of code in C#?
Can this be done better using templating?


My goals are readability and maintainability.

StringBuilder msgBody = new StringBuilder();
msgBody.AppendLine("Deleted Order Item Information");
msgBody.AppendLine("------------------------------------");
msgBody.AppendLine();
msgBody.AppendLine("Delete Date:    {0}".FormatWith(orderDetail.DeletedDate.FormatDateTime(dtFormat)));
msgBody.AppendLine("Delete Comment: {0}".FormatWith(orderDetail.DeletedComment));
msgBody.AppendLine();
msgBody.AppendLine("Order #:        {0}".FormatWith(order.ID.ToString()));
msgBody.AppendLine("Order Date:     {0}".FormatWith(order.SubmitDate.FormatDateTime(dtFormat)));
msgBody.AppendLine("Order Name:     {0}".FormatWith(order.Name));
msgBody.AppendLine("Order Comment:  {0}".FormatWith(order.Comment));
msgBody.AppendLine("Department:     {0}".FormatWith("{0} - {1}".FormatWith(orderDetail.Department, orderDetail.DepartmentDesc)));
msgBody.AppendLine();
msgBody.AppendLine("Item Number:    {0}".FormatWith(orderDetail.StockNumber));
msgBody.AppendLine("Quantity:       {0}".FormatWith(orderDetail.Quantity));
msgBody.AppendLine("Rush:           {0}".FormatWith((orderDetail.Rush.ToYesNo())));
msgBody.AppendLine("Item Name:      {0}".FormatWith(item.Name));
msgBody.AppendLine("Item Desc:      {0}".FormatWith(item.Description1));
msgBody.AppendLine("                {0}".FormatWith(item.Description2));
msgBody.AppendLine("Stock:          {0}".FormatWith((orderDetail.Stock.ToYesNo())));
msgBody.AppendLine("Item Comment:   {0}".FormatWith(orderDetail.Comment));
I have used one template engine in c# by name DotLiquid to resolve similar problems. 


Readability: You have to extract your message template from the code to separate file. The template itself will lives its own life, usually independently from the code. 
Maintainability: 

Collect all required parameters and conditions in one place. Having conditions in your message tends to be next step in real message processing. By the way, anonymous classes from DotLiquid work well with your linq. 
Then: template processing, message composing, and and putting it to queue to sent it. Sending operation itself could be time consuming and quite tricky



Thus I have handled hundreds of template based messages with rich HTML per day. Obviously, if you're going to write next smtp monster,  you'll write a more perfomance optimal solution. But using such template engine is good place to start.

And here is a code snippet:

// Template itself, assume that is has been loaded from file
var messageTemplate = 
@"Deleted Order Item Information
------------------------------------ 

Delete Date:    {{Date}}
Delete Comment: {{DeletedComment}}
… other text";

// Parses and compiles the template
var template = DotLiquid.Template.Parse(messageTemplate);

// Renders the output
var messageBody = template.Render(DotLiquid.Hash.FromAnonymousObject(
    // Parameters
    new {
        Date = DateTime.Today,
        DeletedComment = "Some Comment"
    }));