Мы используем это в MVC, и это прекрасно работает. Поскольку он реализует интерфейс, вы можете внедрить экземпляр в конструктор контроллера вместо использования статического метода:
public class MvcEmailSender : ISendEmails
{
public MvcEmailSender(ILogExceptions logger,
IQueryEntities queryables, IUnitOfWork unitOfWork)
{
// save args to readonly fields on the instance
}
public void Send(EmailMessage message)
{
// constructor really passes more args here
var sender = new SmtpEmailSender(message, arg2, arg3, arg4);
var thread = new Thread(sender.Send);
thread.Start();
}
}
public class SmtpEmailSender
{
private readonly EmailMessage _emailMessage;
private int _retryCount;
public SmtpEmailSender(EmailMessage emailMessage, ILogExceptions logger,
IQueryEntities queryables, IUnitOfWork unitOfWork)
{
if (emailMessage == null)
throw new ArgumentNullException("emailMessage");
_emailMessage = emailMessage;
// save other constructor args to readonly fields
}
public void Send()
{
try
{
// assemble message, send, & update database
}
catch (Exception ex)
{
// log exception, then retry like so:
if (_retryCount++ <= 3)
{
Thread.Sleep(10000);
Send();
}
}
}
}
У нас также есть некоторые настройки в файле web.config, а вы? Если это так, обновите ваш вопрос с помощью раздела system.net в вашем web.config.
Чтобы использовать это, мы просто вызываем ISendEmails.Send (EmailMessage) из контроллера. Реализация заботится о потоке, без ведома MVC.
Оба эти класса и интерфейс ISendEmails объявлены в ссылочных проектах, а не в проекте MVC (интерфейс находится в сборке API, а 2 вышеупомянутых класса в сборке IMPL).
Обновление
Я обновил код в ответ на комментарий. Обратите внимание, что конструкторы этих классов действительно имеют больше зависимостей, чем было изначально изображено. Мы также (конструктор) внедряем зависимости ILogExceptions, IQueryEntities и IUnitOfWork. Внутри блока try, помимо преобразования EmailMessage в MailMessage и отправки, объект домена EmailMessage обновляется в базе данных, а его значение SentOnUtc обновляется после успешного выполнения SmtpClient.Send (MailMessage). Вот как мы доказываем, что электронные письма были действительно отправлены. При обнаружении исключения оно регистрируется перед повторной попыткой.