The following code demonstrates the string.Format usage:
string menuItemName = string.Format("{0}. {1}", item.Number, item.Name);
// Example result: "1. Soup" or "2. Spaghetti"
No rocket science here. String.Format is ideal for these kind of
operations. The following code demonstrates string.Format on a larger
scale:string template =
"Dear {0} {1},\n\n You have requested us to notify when the product '"
"'{3}' would become available for ordering. We are happy to inform'"
" you that it is in stock now, please follow the following link to make an order: \n\n"
"\t\t{4}\n\n"
"With kind regards,\n\n"
"Sales Team";
string message = string.Format(
template,
user.Title,
user.LastName,
product.Name,
orderUrl);
Can you see it's hard to read this template fluently? Your mind is
trying to make sense of the numbers, interpreting their definition
which is found in the parameters of the Format method. Then your mind
must count and figure out which value could be replaced at the right
position. The more parameters, the harder it gets. Avoid these mind
draining constructs, we have better things to do.Here is the same code with name paramters:
string template =
"Dear {Title} {LastName},\n\n You have requested us to notify when the product'"
" '{ProductName} would become available for ordering. We are happy to inform'"
" you that it is in stock now, please follow the following link to make an order: \n\n"
"\t\t{OrderUrl}\n\n"
"With kind regards,\n\n"
"Sales Team";
string message = template.ParseAsTemplate(
new
{
Title = user.Title,
LastName = user.LastName,
ProductName = product.Name,
OrderUrl = orderUrl
});
This read much more fluently. As the example shows, there is an
anonymous variable being created to act as the template's data
container. You could also throw in a predefined object (like a view).
This way you can parse the template immediately without creating a
separate view.To make the code above work, you have to create an extension method that extends string and resides in the root namespace of your application. Like so:
public static string ParseAsTemplate(this string template, object content)
{
var parser = new StringBuilder(template);
var usableProperties =
from property in content.GetType().GetProperties()
where property.CanRead
where property.PropertyType.IsPublic
let value = property.GetValue(content, null)
select new
{
templateVariable = property.Name,
value = value ?? string.Empty
};
foreach (var property in usableProperties)
{
parser.Replace("{" + property.templateVariable + "}", property.value.ToString());
}
return parser.ToString();
}
Notes
Uning this method has a slight pitfall. It uses a StringBuilder to replace for performance reasons, which makes it case sensitive. An anonymous data type can protect you from breaking changes when refactoring, but keep this in mind when throwing in a DTO.It should be noted that extension methods on strings or other basic datatypes is a bad practice. I would advice to discussing implementation with your team to avoid extension methods popping up everywhere and making the dot NET framework look cluttered.
No comments:
Post a Comment