How to use MVCMailer without breaking my service layer?

白昼怎懂夜的黑 提交于 2019-12-03 12:28:41

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:

  1. Probably not practical ... Wait for the version with "Email Sending from a Background Process"

  2. Forget about Smtp from your second project and using Http just call a View which in turn would call MVCMailer

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!