Mi solución fue construir interfaces en la capa de servicio que mis servicios podrían utilizar para obtener un mensaje de correo, mientras que la implementación que crea el mensaje continúa residiendo en la capa web.
Las interfaces están en la capa de servicio:
public interface IMailMessage
{
void Send();
void SendAsync();
}
public interface IUserMailer
{
IMailMessage Welcome(WelcomeMailModel model);
}
Las implementaciones están entonces en la web del proyecto (MVC):
public class MailMessage : MvcMailMessage, IMailMessage
{
}
public class UserMailer : MailerBase, IUserMailer
{
public UserMailer()
{
MasterName = "_Layout";
}
public IMailMessage Welcome(WelcomeMailModel model)
{
var mailMessage = new MailMessage();
mailMessage.SetRecipients(model.To);
mailMessage.Subject = "Welcome";
ViewData = new System.Web.Mvc.ViewDataDictionary(model);
PopulateBody(mailMessage, "Welcome");
return mailMessage;
}
}
Finalmente, en la capa de servicio, la interfaz de cliente de correo es una dependencia del servicio:
public class UserCreationService : IUserCreationService
{
private readonly IUserRepository _repository;
private readonly IUserMailer _userMailer;
public UserCreationService(IUserRepository repository, IUserMailer userMailer)
{
_repository = repository;
_userMailer = userMailer;
}
public void CreateNewUser(string name, string email, string password)
{
// Create the user's account
_repository.Add(new User { Name = name, Email = email, Password = password });
_repository.SaveChanges();
// Now send a welcome email to the user
_userMailer.Welcome(new WelcomeMailModel { Name = name, To = email }).Send();
}
}
Cuando está conectado en inyección de dependencia, un Web. El objeto UserMailer se usa para el parámetro Services.IUserMail para construir el objeto UserCreationService.
He tratado de mantener el ejemplo simple para que sea fácil de seguir, pero una vez que tenga una referencia a IMailMessage en la capa de servicio, puede enviarlo a su código SMTP en lugar de simplemente llamar a Send() como yo lo hago. Para sus propósitos, es posible que necesite desarrollar más la interfaz IMailMessage para acceder a otras partes de la clase MvcMailMessage.
Me preguntaba si podría darme alguna información sobre cómo terminó implementando MVCMailer. – Neil