Realize the mail sending function by combining with the source code of ABP

Source: Internet
Author: User
Tags mailmessage smtpclient

Realize the mail sending function by combining with the source code of ABP

 

  • 1. Preface
  • 2. Implementation Process
    • 1. Code diagram (heavy)
    • 2. Specific implementation
      • 2.1 define etettingnames and AppSettingProvider
      • 2.2 EmailSenderConfiguration Configuration
      • 2.3 SmtpEmailSender implementation (Smtp implements mail sending)
1. Preface

Recently, pm temporarily raised the need for a variety of email verification operations, because no good email sending and receiving components were found at a time, and they also studied the ABC mentality, it took several hours to explore the handling and operation of the Email in the ABP. In fact, most email operations are similar. This time, I just want to introduce the code structure for implementing functions in the ABP. The following describes the specific process.

The displayed version of the ABP code is 0.9.0.0. However, later versions have fewer modifications to this part, so it does not affect the porting of later versions.

2. Implementation Process

The Mail operation of the ABP is placed in the Abp. net. mail and Abp. net. mail. in Smtp, the first step is to take a look at the code diagram of the classes and interfaces in this folder (unavailable without permission)

1. Code diagram (heavy)

According to the Code diagram, it can be found that the content of abcfor Mail processing is mainly composed of three parts:

  • The first part is to set Mail-related parameters by inheriting the EmailSettingProvider of SettingProvider (where EmailSettingNames defines relevant strings)
  • The second part is an operation class derived from the IEmailSenderConfiguration interface to read and transmit the mail parameters set by SettingProvider.
  • The third part is the Mail sending operation class derived from the IEmailSender interface.

For Files starting with Smtp, it is only an implementation file that is sent by mail in the form of Smtp, and this method will be directly used for processing later.

2. Specific implementation

In specific implementation, I found that the Mail-related classes of the ABP itself are very complete, but the custom implementation is needed in the Mail parameter configuration, so I directly extracted the source code of the ABP for demonstration.

2.1 define etettingnames and AppSettingProvider

The unique string defined in AppSettingNames can be considered as the Key, while the parameter ettingprovider assigns values to the mail parameter corresponding to the Key for later Configuration reading.

The mail function is recommended to be placed in the Core module. After the related provider is completed, add it to CoreModule.Configuration.Settings.Providers.Add<AppSettingProvider>();To take effect

public static class AppSettings{    /// <summary>    /// SMTP related email settings.    /// </summary>    public static class Smtp    {        /// <summary>        /// Abp.Net.Mail.DefaultFromAddress        /// </summary>        public const string DefaultAddress = "Trucking.Net.Mail.DefaultFromAddress";        /// <summary>        /// Abp.Net.Mail.DefaultFromDisplayName        /// </summary>        public const string DefaultDisplayName = "Trucking.Net.Mail.DefaultFromDisplayName";        /// <summary>        /// Abp.Net.Mail.Smtp.Host        /// </summary>        public const string Host = "Trucking.Net.Mail.Smtp.Host";        /// <summary>        /// Abp.Net.Mail.Smtp.Port        /// </summary>        public const string Port = "Trucking.Net.Mail.Smtp.Port";        /// <summary>        /// Abp.Net.Mail.Smtp.UserName        /// </summary>        public const string UserName = "Trucking.Net.Mail.Smtp.UserName";        /// <summary>        /// Abp.Net.Mail.Smtp.Password        /// </summary>        public const string Password = "Trucking.Net.Mail.Smtp.Password";        /// <summary>        /// Abp.Net.Mail.Smtp.Domain        /// </summary>        public const string Domain = "Trucking.Net.Mail.Smtp.Domain";        /// <summary>        /// Abp.Net.Mail.Smtp.EnableSsl        /// </summary>        public const string EnableSsl = "Trucking.Net.Mail.Smtp.EnableSsl";        /// <summary>        /// Abp.Net.Mail.Smtp.UseDefaultCredentials        /// </summary>        public const string UseDefaultCredentials = "Trucking.Net.Mail.Smtp.UseDefaultCredentials";    }}public class AppSettingProvider : SettingProvider{    public override IEnumerable<SettingDefinition> GetSettingDefinitions(SettingDefinitionProviderContext context)    {        return new[]        {            new SettingDefinition(AppSettings.Smtp.Host, "smtp.gmail.com", L("SmtpHost"),                scopes: SettingScopes.Application | SettingScopes.Tenant),            new SettingDefinition(AppSettings.Smtp.Port, "587", L("SmtpPort"),                scopes: SettingScopes.Application | SettingScopes.Tenant),            new SettingDefinition(AppSettings.Smtp.UserName, "myemail@gmail.com", L("Username"),                scopes: SettingScopes.Application | SettingScopes.Tenant),            new SettingDefinition(AppSettings.Smtp.Password, "mypassword", L("Password"),                scopes: SettingScopes.Application | SettingScopes.Tenant),            new SettingDefinition(AppSettings.Smtp.Domain, "", L("DomainName"),                scopes: SettingScopes.Application | SettingScopes.Tenant),            new SettingDefinition(AppSettings.Smtp.EnableSsl, "true", L("UseSSL"),                scopes: SettingScopes.Application | SettingScopes.Tenant),            new SettingDefinition(AppSettings.Smtp.UseDefaultCredentials, "false", L("UseDefaultCredentials"),                scopes: SettingScopes.Application | SettingScopes.Tenant),            new SettingDefinition(AppSettings.Smtp.DefaultAddress, "myemail@gmail.com",                L("DefaultEmailAddress"), scopes: SettingScopes.Application | SettingScopes.Tenant),            new SettingDefinition(AppSettings.Smtp.DefaultDisplayName, "CompanyName",                L("DefaultDisplayName"), scopes: SettingScopes.Application | SettingScopes.Tenant)        };    }    private static LocalizableString L(string name)    {        return new LocalizableString(name, AbpConsts.LocalizationSourceName);    }}
2.2 EmailSenderConfiguration Configuration

As mentioned above, this class is mainly used to read the mail parameter value set in the Custom AppSettingProvider.

IUserEmailSenderConfiguration interface omitted

public class UserEmailSenderConfiguration : TruckingServiceBase, IUserEmailSenderConfiguration, ITransientDependency{    /// <summary>    /// Gets a setting value by checking. Throws <see cref="AbpException"/> if it's null or empty.    /// </summary>    /// <param name="name">Name of the setting</param>    /// <returns>Value of the setting</returns>    protected string GetNotEmptySettingValue(string name)    {        var value = SettingManager.GetSettingValue(name);        if (value.IsNullOrEmpty())        {            throw new AbpException(String.Format("Setting value for '{0}' is null or empty!", name));        }        return value;    }    /// <summary>    /// SMTP Host name/IP.    /// </summary>    public string Host    {        get { return GetNotEmptySettingValue(AppSettings.Smtp.Host); }    }    /// <summary>    /// SMTP Port.    /// </summary>    public int Port    {        get { return SettingManager.GetSettingValue<int>(AppSettings.Smtp.Port); }    }    /// <summary>    /// User name to login to SMTP server.    /// </summary>    public string UserName    {        get { return GetNotEmptySettingValue(AppSettings.Smtp.UserName); }    }    /// <summary>    /// Password to login to SMTP server.    /// </summary>    public string Password    {        get { return GetNotEmptySettingValue(AppSettings.Smtp.Password); }    }    /// <summary>    /// Domain name to login to SMTP server.    /// </summary>    public string Domain    {        get { return SettingManager.GetSettingValue(AppSettings.Smtp.Domain); }    }    /// <summary>    /// Is SSL enabled?    /// </summary>    public bool EnableSsl    {        get { return SettingManager.GetSettingValue<bool>(AppSettings.Smtp.EnableSsl); }    }    /// <summary>    /// Use default credentials?    /// </summary>    public bool UseDefaultCredentials    {        get { return SettingManager.GetSettingValue<bool>(AppSettings.Smtp.UseDefaultCredentials); }    }    public string DefaultAddress    {        get { return GetNotEmptySettingValue(AppSettings.Smtp.DefaultAddress); }    }    public string DefaultDisplayName    {        get { return SettingManager.GetSettingValue(AppSettings.Smtp.DefaultDisplayName); }    }}
2.3 SmtpEmailSender implementation (Smtp implements mail sending)

The UserSmtpEmailSender class is the true Mail operation class. It injects the IUserEmailSenderConfiguration interface to read related Mail parameters, such as Host, UserName, and Password, and then calls. NET Mail to send emails.

IUserSmtpEmailSender interface omitted

public class UserSmtpEmailSender : IUserSmtpEmailSender, ITransientDependency{    private readonly IUserEmailSenderConfiguration _configuration;    public UserSmtpEmailSender(IUserEmailSenderConfiguration configuration)    {        _configuration = configuration;    }        public async Task SendAsync(string to, string subject, string body, bool isBodyHtml = true)    {        await SendAsync(_configuration.DefaultAddress, to, subject, body, isBodyHtml);    }    public void Send(string to, string subject, string body, bool isBodyHtml = true)    {        Send(_configuration.DefaultAddress, to, subject, body, isBodyHtml);    }    public async Task SendAsync(string from, string to, string subject, string body, bool isBodyHtml = true)    {        await SendAsync(new MailMessage(from, to, subject, body) {IsBodyHtml = isBodyHtml});    }    public void Send(string from, string to, string subject, string body, bool isBodyHtml = true)    {        Send(new MailMessage(from, to, subject, body) {IsBodyHtml = isBodyHtml});    }    public async Task SendAsync(MailMessage mail, bool normalize = true)    {        if (normalize)            NormalizeMail(mail);        await SendEmailAsync(mail);    }    public void Send(MailMessage mail, bool normalize = true)    {        if (normalize)            NormalizeMail(mail);        SendEmail(mail);    }    public SmtpClient BuildClient()    {        var host = _configuration.Host;        var port = _configuration.Port;        var smtpClient = new SmtpClient(host, port);        try        {            if (_configuration.EnableSsl)                smtpClient.EnableSsl = true;            if (_configuration.UseDefaultCredentials)            {                smtpClient.UseDefaultCredentials = true;            }            else            {                smtpClient.UseDefaultCredentials = false;                var userName = _configuration.UserName;                if (!userName.IsNullOrEmpty())                {                    var password = _configuration.Password;                    var domain = _configuration.Domain;                    smtpClient.Credentials = !domain.IsNullOrEmpty()                        ? new NetworkCredential(userName, password, domain)                        : new NetworkCredential(userName, password);            }        }                return smtpClient;    }    catch    {            smtpClient.Dispose();            throw;        }    }    /// <summary>    ///     Normalizes given email.    ///     Fills <see cref="MailMessage.From" /> if it's not filled before.    ///     Sets encodings to UTF8 if they are not set before.    /// </summary>    /// <param name="mail">Mail to be normalized</param>    protected virtual void NormalizeMail(MailMessage mail)    {        if ((mail.From == null) || mail.From.Address.IsNullOrEmpty())            mail.From = new MailAddress(                _configuration.DefaultAddress,                _configuration.DefaultDisplayName,                Encoding.UTF8            );        if (mail.HeadersEncoding == null)            mail.HeadersEncoding = Encoding.UTF8;        if (mail.SubjectEncoding == null)            mail.SubjectEncoding = Encoding.UTF8;        if (mail.BodyEncoding == null)            mail.BodyEncoding = Encoding.UTF8;    }    protected async Task SendEmailAsync(MailMessage mail)    {        using (var smtpClient = BuildClient())        {            await smtpClient.SendMailAsync(mail);        }    }    protected void SendEmail(MailMessage mail)    {        using (var smtpClient = BuildClient())        {            smtpClient.Send(mail);        }    }}

 

Then we only need to call SendAsync of the EmailSender and fill in the corresponding parameters, which is valid for test. If you want to change the mail component, you only need to implement the corresponding UserLibraryEmailSerder.

So far, we have extracted a separate email function from the ABC and explained it. In fact, you only need to spend some time to manually strip the code diagram. Why is the implementation of a Simple Mail function so complicated in the ABC? Every programmer has the answer from every programmer. Continue to learn.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.