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

Building an email body

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

Problem

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

Solution

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

Code Snippets

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

Context

StackExchange Code Review Q#14089, answer score: 6

Revisions (0)

No revisions yet.