How to use MVCMailer without breaking my service layer?
I am looking into using MVcMailer to make nicer emails.
However one thing that I am unsure is how to organize the code. I currently have 2 projects. One for mvc and one for my repos and service layers.
my 2nd project has no knowledge of MVC and I would like to keep it that way.
I am thinking that my smtp code would go into a service layer or wrapper and then I would call it up from other service layers when I need to send emails out.
开发者_运维知识库So where does the MVC mailer fit in? Do I generate the body in the controller then pass it to a serivce layer that passes it to my smtp class?
My solution was to build interfaces in the service layer that my services could then use to get a mail message, while the implementation that creates the message continues to reside in the web layer.
The interfaces are in the service layer:
public interface IMailMessage
{
void Send();
void SendAsync();
}
public interface IUserMailer
{
IMailMessage Welcome(WelcomeMailModel model);
}
The implementations are then in the web (MVC) project:
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;
}
}
Finally in the service layer, the mailer interface is a dependency of the service:
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();
}
}
When it's wired up in dependency injection, a Web.UserMailer object is used for the Services.IUserMail parameter to construct the UserCreationService object.
I've tried to keep the example simple so that it is easy to follow, but once you have a reference to an IMailMessage in the service layer, you can send it to your SMTP code instead of just calling Send() as I do. For your purposes, you may need to flesh out the IMailMessage interface more in order to access other parts of the MvcMailMessage class.
MVCMailer seems to already have support for sending email. If you setup the config correctly it should be able to email the populated MailerViews without additional implementation.
I am not sure of the role of your second project in you solution but here are two possibilities:
Probably not practical ... Wait for the version with "Email Sending from a Background Process"
Forget about Smtp from your second project and using Http just call a View which in turn would call MVCMailer
精彩评论