mirror of https://github.com/abpframework/abp.git
14 changed files with 569 additions and 3 deletions
@ -0,0 +1,121 @@ |
|||
using System; |
|||
using System.Net.Mail; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.Abp.Emailing |
|||
{ |
|||
/// <summary>
|
|||
/// This class can be used as base to implement <see cref="IEmailSender"/>.
|
|||
/// </summary>
|
|||
public abstract class EmailSenderBase : IEmailSender |
|||
{ |
|||
public IEmailSenderConfiguration Configuration { get; } |
|||
|
|||
/// <summary>
|
|||
/// Constructor.
|
|||
/// </summary>
|
|||
/// <param name="configuration">Configuration</param>
|
|||
protected EmailSenderBase(IEmailSenderConfiguration configuration) |
|||
{ |
|||
Configuration = configuration; |
|||
} |
|||
|
|||
public virtual async Task SendAsync(string to, string subject, string body, bool isBodyHtml = true) |
|||
{ |
|||
await SendAsync(new MailMessage |
|||
{ |
|||
To = { to }, |
|||
Subject = subject, |
|||
Body = body, |
|||
IsBodyHtml = isBodyHtml |
|||
}); |
|||
} |
|||
|
|||
public virtual void Send(string to, string subject, string body, bool isBodyHtml = true) |
|||
{ |
|||
Send(new MailMessage |
|||
{ |
|||
To = { to }, |
|||
Subject = subject, |
|||
Body = body, |
|||
IsBodyHtml = isBodyHtml |
|||
}); |
|||
} |
|||
|
|||
public virtual 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 virtual void Send(string from, string to, string subject, string body, bool isBodyHtml = true) |
|||
{ |
|||
Send(new MailMessage(from, to, subject, body) { IsBodyHtml = isBodyHtml }); |
|||
} |
|||
|
|||
public virtual async Task SendAsync(MailMessage mail, bool normalize = true) |
|||
{ |
|||
if (normalize) |
|||
{ |
|||
NormalizeMail(mail); |
|||
} |
|||
|
|||
await SendEmailAsync(mail); |
|||
} |
|||
|
|||
public virtual void Send(MailMessage mail, bool normalize = true) |
|||
{ |
|||
if (normalize) |
|||
{ |
|||
NormalizeMail(mail); |
|||
} |
|||
|
|||
SendEmail(mail); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Should implement this method to send email in derived classes.
|
|||
/// </summary>
|
|||
/// <param name="mail">Mail to be sent</param>
|
|||
protected abstract Task SendEmailAsync(MailMessage mail); |
|||
|
|||
/// <summary>
|
|||
/// Should implement this method to send email in derived classes.
|
|||
/// </summary>
|
|||
/// <param name="mail">Mail to be sent</param>
|
|||
protected abstract void SendEmail(MailMessage mail); |
|||
|
|||
/// <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.DefaultFromAddress, |
|||
Configuration.DefaultFromDisplayName, |
|||
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; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
using System; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace Volo.Abp.Emailing |
|||
{ |
|||
/// <summary>
|
|||
/// Implementation of <see cref="IEmailSenderConfiguration"/> that reads settings
|
|||
/// from <see cref="ISettingManager"/>.
|
|||
/// </summary>
|
|||
public abstract class EmailSenderConfiguration : IEmailSenderConfiguration |
|||
{ |
|||
public virtual string DefaultFromAddress => GetNotEmptySettingValue(EmailSettingNames.DefaultFromAddress); |
|||
|
|||
public virtual string DefaultFromDisplayName => SettingManager.GetOrNull(EmailSettingNames.DefaultFromDisplayName); |
|||
|
|||
protected readonly ISettingManager SettingManager; |
|||
|
|||
/// <summary>
|
|||
/// Creates a new <see cref="EmailSenderConfiguration"/>.
|
|||
/// </summary>
|
|||
protected EmailSenderConfiguration(ISettingManager settingManager) |
|||
{ |
|||
SettingManager = settingManager; |
|||
} |
|||
|
|||
/// <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.GetOrNull(name); |
|||
|
|||
if (value.IsNullOrEmpty()) |
|||
{ |
|||
throw new AbpException($"Setting value for '{name}' is null or empty!"); |
|||
} |
|||
|
|||
return value; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,59 @@ |
|||
namespace Volo.Abp.Emailing |
|||
{ |
|||
/// <summary>
|
|||
/// Declares names of the settings defined by <see cref="EmailSettingProvider"/>.
|
|||
/// </summary>
|
|||
public static class EmailSettingNames |
|||
{ |
|||
/// <summary>
|
|||
/// Abp.Net.Mail.DefaultFromAddress
|
|||
/// </summary>
|
|||
public const string DefaultFromAddress = "Abp.Net.Mail.DefaultFromAddress"; |
|||
|
|||
/// <summary>
|
|||
/// Abp.Net.Mail.DefaultFromDisplayName
|
|||
/// </summary>
|
|||
public const string DefaultFromDisplayName = "Abp.Net.Mail.DefaultFromDisplayName"; |
|||
|
|||
/// <summary>
|
|||
/// SMTP related email settings.
|
|||
/// </summary>
|
|||
public static class Smtp |
|||
{ |
|||
/// <summary>
|
|||
/// Abp.Net.Mail.Smtp.Host
|
|||
/// </summary>
|
|||
public const string Host = "Abp.Net.Mail.Smtp.Host"; |
|||
|
|||
/// <summary>
|
|||
/// Abp.Net.Mail.Smtp.Port
|
|||
/// </summary>
|
|||
public const string Port = "Abp.Net.Mail.Smtp.Port"; |
|||
|
|||
/// <summary>
|
|||
/// Abp.Net.Mail.Smtp.UserName
|
|||
/// </summary>
|
|||
public const string UserName = "Abp.Net.Mail.Smtp.UserName"; |
|||
|
|||
/// <summary>
|
|||
/// Abp.Net.Mail.Smtp.Password
|
|||
/// </summary>
|
|||
public const string Password = "Abp.Net.Mail.Smtp.Password"; |
|||
|
|||
/// <summary>
|
|||
/// Abp.Net.Mail.Smtp.Domain
|
|||
/// </summary>
|
|||
public const string Domain = "Abp.Net.Mail.Smtp.Domain"; |
|||
|
|||
/// <summary>
|
|||
/// Abp.Net.Mail.Smtp.EnableSsl
|
|||
/// </summary>
|
|||
public const string EnableSsl = "Abp.Net.Mail.Smtp.EnableSsl"; |
|||
|
|||
/// <summary>
|
|||
/// Abp.Net.Mail.Smtp.UseDefaultCredentials
|
|||
/// </summary>
|
|||
public const string UseDefaultCredentials = "Abp.Net.Mail.Smtp.UseDefaultCredentials"; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace Volo.Abp.Emailing |
|||
{ |
|||
/// <summary>
|
|||
/// Defines settings to send emails.
|
|||
/// <see cref="EmailSettingNames"/> for all available configurations.
|
|||
/// </summary>
|
|||
internal class EmailSettingProvider : SettingDefinitionProvider |
|||
{ |
|||
public override void Define(ISettingDefinitionContext context) |
|||
{ |
|||
context.Add( |
|||
new SettingDefinition(EmailSettingNames.Smtp.Host, "127.0.0.1"), |
|||
new SettingDefinition(EmailSettingNames.Smtp.Port, "25"), |
|||
new SettingDefinition(EmailSettingNames.Smtp.UserName), |
|||
new SettingDefinition(EmailSettingNames.Smtp.Password), |
|||
new SettingDefinition(EmailSettingNames.Smtp.Domain), |
|||
new SettingDefinition(EmailSettingNames.Smtp.EnableSsl, "false"), |
|||
new SettingDefinition(EmailSettingNames.Smtp.UseDefaultCredentials, "true"), |
|||
new SettingDefinition(EmailSettingNames.DefaultFromAddress), |
|||
new SettingDefinition(EmailSettingNames.DefaultFromDisplayName) |
|||
); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
using System.Net.Mail; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.Abp.Emailing |
|||
{ |
|||
/// <summary>
|
|||
/// This service can be used simply sending emails.
|
|||
/// </summary>
|
|||
public interface IEmailSender |
|||
{ |
|||
/// <summary>
|
|||
/// Sends an email.
|
|||
/// </summary>
|
|||
Task SendAsync(string to, string subject, string body, bool isBodyHtml = true); |
|||
|
|||
/// <summary>
|
|||
/// Sends an email.
|
|||
/// </summary>
|
|||
void Send(string to, string subject, string body, bool isBodyHtml = true); |
|||
|
|||
/// <summary>
|
|||
/// Sends an email.
|
|||
/// </summary>
|
|||
Task SendAsync(string from, string to, string subject, string body, bool isBodyHtml = true); |
|||
|
|||
/// <summary>
|
|||
/// Sends an email.
|
|||
/// </summary>
|
|||
void Send(string from, string to, string subject, string body, bool isBodyHtml = true); |
|||
|
|||
/// <summary>
|
|||
/// Sends an email.
|
|||
/// </summary>
|
|||
/// <param name="mail">Mail to be sent</param>
|
|||
/// <param name="normalize">
|
|||
/// Should normalize email?
|
|||
/// If true, it sets sender address/name if it's not set before and makes mail encoding UTF-8.
|
|||
/// </param>
|
|||
void Send(MailMessage mail, bool normalize = true); |
|||
|
|||
/// <summary>
|
|||
/// Sends an email.
|
|||
/// </summary>
|
|||
/// <param name="mail">Mail to be sent</param>
|
|||
/// <param name="normalize">
|
|||
/// Should normalize email?
|
|||
/// If true, it sets sender address/name if it's not set before and makes mail encoding UTF-8.
|
|||
/// </param>
|
|||
Task SendAsync(MailMessage mail, bool normalize = true); |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
namespace Volo.Abp.Emailing |
|||
{ |
|||
/// <summary>
|
|||
/// Defines configurations used while sending emails.
|
|||
/// </summary>
|
|||
public interface IEmailSenderConfiguration |
|||
{ |
|||
/// <summary>
|
|||
/// Default from address.
|
|||
/// </summary>
|
|||
string DefaultFromAddress { get; } |
|||
|
|||
/// <summary>
|
|||
/// Default display name.
|
|||
/// </summary>
|
|||
string DefaultFromDisplayName { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
using System.Net.Mail; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Logging.Abstractions; |
|||
|
|||
namespace Volo.Abp.Emailing |
|||
{ |
|||
/// <summary>
|
|||
/// This class is an implementation of <see cref="IEmailSender"/> as similar to null pattern.
|
|||
/// It does not send emails but logs them.
|
|||
/// </summary>
|
|||
public class NullEmailSender : EmailSenderBase |
|||
{ |
|||
public ILogger<NullEmailSender> Logger { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Creates a new <see cref="NullEmailSender"/> object.
|
|||
/// </summary>
|
|||
/// <param name="configuration">Configuration</param>
|
|||
public NullEmailSender(IEmailSenderConfiguration configuration) |
|||
: base(configuration) |
|||
{ |
|||
Logger = NullLogger<NullEmailSender>.Instance; |
|||
} |
|||
|
|||
protected override Task SendEmailAsync(MailMessage mail) |
|||
{ |
|||
Logger.LogWarning("USING NullEmailSender!"); |
|||
Logger.LogDebug("SendEmailAsync:"); |
|||
LogEmail(mail); |
|||
return Task.FromResult(0); |
|||
} |
|||
|
|||
protected override void SendEmail(MailMessage mail) |
|||
{ |
|||
Logger.LogWarning("USING NullEmailSender!"); |
|||
Logger.LogWarning("SendEmail:"); |
|||
LogEmail(mail); |
|||
} |
|||
|
|||
private void LogEmail(MailMessage mail) |
|||
{ |
|||
Logger.LogDebug(mail.To.ToString()); |
|||
Logger.LogDebug(mail.CC.ToString()); |
|||
Logger.LogDebug(mail.Subject); |
|||
Logger.LogDebug(mail.Body); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using System.Net.Mail; |
|||
|
|||
namespace Volo.Abp.Emailing.Smtp |
|||
{ |
|||
/// <summary>
|
|||
/// Used to send emails over SMTP.
|
|||
/// </summary>
|
|||
public interface ISmtpEmailSender : IEmailSender |
|||
{ |
|||
/// <summary>
|
|||
/// Creates and configures new <see cref="SmtpClient"/> object to send emails.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// An <see cref="SmtpClient"/> object that is ready to send emails.
|
|||
/// </returns>
|
|||
SmtpClient BuildClient(); |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
namespace Volo.Abp.Emailing.Smtp |
|||
{ |
|||
/// <summary>
|
|||
/// Defines configurations to used by SmtpClient object.
|
|||
/// </summary>
|
|||
public interface ISmtpEmailSenderConfiguration : IEmailSenderConfiguration |
|||
{ |
|||
/// <summary>
|
|||
/// SMTP Host name/IP.
|
|||
/// </summary>
|
|||
string Host { get; } |
|||
|
|||
/// <summary>
|
|||
/// SMTP Port.
|
|||
/// </summary>
|
|||
int Port { get; } |
|||
|
|||
/// <summary>
|
|||
/// User name to login to SMTP server.
|
|||
/// </summary>
|
|||
string UserName { get; } |
|||
|
|||
/// <summary>
|
|||
/// Password to login to SMTP server.
|
|||
/// </summary>
|
|||
string Password { get; } |
|||
|
|||
/// <summary>
|
|||
/// Domain name to login to SMTP server.
|
|||
/// </summary>
|
|||
string Domain { get; } |
|||
|
|||
/// <summary>
|
|||
/// Is SSL enabled?
|
|||
/// </summary>
|
|||
bool EnableSsl { get; } |
|||
|
|||
/// <summary>
|
|||
/// Use default credentials?
|
|||
/// </summary>
|
|||
bool UseDefaultCredentials { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,83 @@ |
|||
using System; |
|||
using System.Net; |
|||
using System.Net.Mail; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Emailing.Smtp |
|||
{ |
|||
/// <summary>
|
|||
/// Used to send emails over SMTP.
|
|||
/// </summary>
|
|||
public class SmtpEmailSender : EmailSenderBase, ISmtpEmailSender, ITransientDependency |
|||
{ |
|||
private readonly ISmtpEmailSenderConfiguration _configuration; |
|||
|
|||
/// <summary>
|
|||
/// Creates a new <see cref="SmtpEmailSender"/>.
|
|||
/// </summary>
|
|||
/// <param name="configuration">Configuration</param>
|
|||
public SmtpEmailSender(ISmtpEmailSenderConfiguration configuration) |
|||
: base(configuration) |
|||
{ |
|||
_configuration = configuration; |
|||
} |
|||
|
|||
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; |
|||
} |
|||
} |
|||
|
|||
protected override async Task SendEmailAsync(MailMessage mail) |
|||
{ |
|||
using (var smtpClient = BuildClient()) |
|||
{ |
|||
await smtpClient.SendMailAsync(mail); |
|||
} |
|||
} |
|||
|
|||
protected override void SendEmail(MailMessage mail) |
|||
{ |
|||
using (var smtpClient = BuildClient()) |
|||
{ |
|||
smtpClient.Send(mail); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
using System; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.Settings; |
|||
|
|||
namespace Volo.Abp.Emailing.Smtp |
|||
{ |
|||
/// <summary>
|
|||
/// Implementation of <see cref="ISmtpEmailSenderConfiguration"/> that reads settings
|
|||
/// from <see cref="ISettingManager"/>.
|
|||
/// </summary>
|
|||
public class SmtpEmailSenderConfiguration : EmailSenderConfiguration, ISmtpEmailSenderConfiguration, ITransientDependency |
|||
{ |
|||
public virtual string Host => GetNotEmptySettingValue(EmailSettingNames.Smtp.Host); |
|||
|
|||
public virtual int Port => GetNotEmptySettingValue(EmailSettingNames.Smtp.Port).To<int>(); |
|||
|
|||
public virtual string UserName => GetNotEmptySettingValue(EmailSettingNames.Smtp.UserName); |
|||
|
|||
public virtual string Password => GetNotEmptySettingValue(EmailSettingNames.Smtp.Password); |
|||
|
|||
public virtual string Domain => SettingManager.GetOrNull(EmailSettingNames.Smtp.Domain); |
|||
|
|||
public virtual bool EnableSsl => SettingManager.GetOrNull(EmailSettingNames.Smtp.EnableSsl).To<bool>(); |
|||
|
|||
public virtual bool UseDefaultCredentials => SettingManager.GetOrNull(EmailSettingNames.Smtp.UseDefaultCredentials).To<bool>(); |
|||
|
|||
public SmtpEmailSenderConfiguration(ISettingManager settingManager) |
|||
: base(settingManager) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
} |
|||
@ -1,8 +1,23 @@ |
|||
namespace Volo.Abp.Settings |
|||
using System.Collections.Generic; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace Volo.Abp.Settings |
|||
{ |
|||
public static class SettingManagerSyncExtensions |
|||
{ |
|||
//TODO: Add sync extension methods for all setting manager methods.
|
|||
//TODO: Also add sync extension methods for all value provider extensions (like GlobalSettingManagerExtensions).
|
|||
public static string GetOrNull([NotNull] this ISettingManager settingManager, [NotNull] string name) |
|||
{ |
|||
Check.NotNull(settingManager, nameof(settingManager)); |
|||
|
|||
return AsyncHelper.RunSync(() => settingManager.GetOrNullAsync(name)); |
|||
} |
|||
|
|||
public static List<SettingValue> GetAll([NotNull] this ISettingManager settingManager) |
|||
{ |
|||
Check.NotNull(settingManager, nameof(settingManager)); |
|||
|
|||
return AsyncHelper.RunSync(settingManager.GetAllAsync); |
|||
} |
|||
} |
|||
} |
|||
|
|||
Loading…
Reference in new issue