views:

33

answers:

1

I am working on a component for merging arbitrary tokens with text in order to generate e-mails. I am going to be using nvelocity for the merging process, so I have defined the following interface:

public interface ITemplateEngine
{
    string Merge(string template, IDictionary<string, object> data);
}

Now, in my scenario, the implementing class returns a string containing xml (subject, body nodes). Next, I need a intermediate class used to return a mail item. Here is the class.

    public class MailMessageBuilder : IMailMessageBuilder
{
    private readonly ITemplateEngine engine;

    public MailMessageBuilder(ITemplateEngine engine)
    {
        this.engine = engine;
    }

    public MailMessage Build(string name, IDictionary<string, object> tokens)
    {
        var doc = new XmlDocument();
        doc.LoadXml(engine.Merge(name, tokens));

        var msg = new MailMessage();
        var node = doc.DocumentElement.SelectSingleNode("Body");

        msg.Body = node.InnerText;
        msg.IsBodyHtml = bool.Parse(node.Attributes.GetNamedItem("isHtml").Value);
        msg.Subject = doc.DocumentElement.SelectSingleNode("Subject").InnerText;

        return msg;
    }
}

Now to my real question, do you think my mail message builder class is doing more than he should since he is pulling out the values from the xml? If so, any other design ideas?

Thanks!

A: 

Now to my real question, do you think my mail message builder class is doing more than he should since he is pulling out the values from the xml? If so, any other design ideas?

I think its fine that he's pulling out values from the XML and putting them in the MailMessage class since the only way to abstract that would be to extract the values into something else that you then mapped over to MailMessage. In other words, that part is doing only one thing, mapping the XML into your MailMessage.

The place where I think you might be violating SRP is in doing the Engine.Merge call inside there, that seems like it should be done externally to the function and the string result passed in instead of the name and Dictionary. (I'd also change that MailMessageBuilder so that the parameter name does not match exactly the private member name, which forces you to use "this", but that's a minor point.)

kekekela
Nice suggestion, I changed the IMailMessageBuilder interface to include a generic arg in order to have multiple types (xml, data table, etc).thanks!
Marco