I've made an object that both has a method for sending an email via a web service and some state for reporting on how it went. An instance for this object will exist for every email address in a list of addresses to which a canned email message will be broadcast. The methods for the instance objects will get spooled up in a Func and then fired off at once.
using System;
namespace Funky.Core
{
public class EmailAttempt
{
public string Error { get; set; }
public EmailSendingStatus Status { get; set; }
public string ToAddress { get; private set; }
public EmailAttempt(string email)
{
ToAddress = email;
Status = EmailSendingStatus.Unsent;
Error = null;
}
public DateTime Attempt(Tuple<string, string, string> htmlPasswordAndSubject,
IEmailSender emailSender, IClock clock)
{
try
{
emailSender.Send(ToAddress, htmlPasswordAndSubject.Item1,
htmlPasswordAndSubject.Item2, htmlPasswordAndSubject.Item3);
Status = EmailSendingStatus.Successful;
}
catch (Exception exception)
{
Status = EmailSendingStatus.Failed;
Error = exception.Message;
}
return clock.Time();
}
}
}
Here is an enum used by my object. This is for delineating if a would-be attempt has been processed and how the processing faired.
namespace Funky.Core
{
public enum EmailSendingStatus
{
Failed,
Successful,
Unsent
}
}
Here is a static method for populating and then executing the Func mentioned. It will return a list of objects which denote how each would-be outbound email faired and also a note about when the whole of the greater operation ended.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Funky.Core
{
public static class EmailSenderWrapper
{
public static Tuple<List<EmailAttempt>, string> SendToList(List<string> emails,
Tuple<string, string, string> htmlPasswordAndSubject, IEmailSender
emailSender, IClock clock)
{
List<EmailAttempt> attempts = emails.Select(email => new
EmailAttempt(email)).ToList();
string endStatus = CommonMagicStrings.EmailSpoolEmptyMessage();
if (attempts.Count > 0)
{
Func<Tuple<string, string, string>, IEmailSender, IClock, DateTime> queue;
queue = attempts[0].Attempt;
if (attempts.Count > 1)
{
int counter = 1;
while (counter < attempts.Count)
{
queue += attempts[counter].Attempt;
counter++;
}
}
DateTime endTime = queue(htmlPasswordAndSubject, emailSender, clock);
endStatus =
String.Format(CommonMagicStrings.EmailSpoolCompletionMessage(),
endTime.ToString());
}
return new Tuple<List<EmailAttempt>, string>(attempts, endStatus);
}
}
}
Here is an example of use.
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using Funky.Core;
using StructureMap;
namespace Funky.UserInterface.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
IEmailSender emailSender = ObjectFactory.GetInstance<IEmailSender>();
IClock clock = ObjectFactory.GetInstance<IClock>();
Tuple<string, string, string> htmlPasswordAndSubject = new Tuple<string, string,
string>("Body", "Xenu", "Header");
List<string> emails = new List<string>() {"fevercheese@gmail.com",
"tomjaeschke@tomjaeschke.com"};
Tuple<List<EmailAttempt>, string> detailsAndStatusOfEmailCampaign =
EmailSenderWrapper.SendToList(emails, htmlPasswordAndSubject,
emailSender, clock);
return View(detailsAndStatusOfEmailCampaign);
}
}
}
No comments:
Post a Comment