From 5e3767036f5fc5dddf68643546e6b081491be58d Mon Sep 17 00:00:00 2001 From: milimoe <110188673+milimoe@users.noreply.github.com> Date: Sat, 24 Jun 2023 01:33:40 +0800 Subject: [PATCH] Extend MailServices (#35) --- Api/Transmittal/MailSender.cs | 51 +++++++ Library/Common/Network/MailObject.cs | 194 +++++++++++++++++++++++++-- Service/MailManager.cs | 68 +++++++--- 3 files changed, 283 insertions(+), 30 deletions(-) diff --git a/Api/Transmittal/MailSender.cs b/Api/Transmittal/MailSender.cs index 086fedc..5b6b830 100644 --- a/Api/Transmittal/MailSender.cs +++ b/Api/Transmittal/MailSender.cs @@ -8,26 +8,70 @@ namespace Milimoe.FunGame.Core.Api.Transmittal { public class MailSender : IDisposable { + /// + /// 邮件服务内部ID + /// public Guid MailSenderID { get; } + + /// + /// Smtp客户端信息 + /// public SmtpClientInfo SmtpClientInfo => _SmtpClientInfo; + + /// + /// 上一个邮件发送的结果 + /// public MailSendResult LastestResult => _LastestResult; + + /// + /// 上一个邮件的发送错误信息(如果发送失败) + /// public string ErrorMsg => _ErrorMsg; + /** + * 内部变量 + */ private readonly SmtpClientInfo _SmtpClientInfo; private MailSendResult _LastestResult = MailSendResult.NotSend; private string _ErrorMsg = ""; + /// + /// 创建邮件服务 + /// + /// + /// + /// + /// + /// + /// public MailSender(string SenderMailAddress, string SenderName, string SenderPassword, string Host, int Port, bool OpenSSL) { MailSenderID = Guid.NewGuid(); _SmtpClientInfo = new SmtpClientInfo(SenderMailAddress, SenderName, SenderPassword, Host, Port, OpenSSL); + if (!MailManager.MailSenders.ContainsKey(MailSenderID)) MailManager.MailSenders.Add(MailSenderID, this); } + /// + /// 创建完整邮件对象 + /// + /// + /// + /// + /// + /// + /// + /// + /// public MailObject CreateMail(string Subject, string Body, MailPriority Priority, bool HTML, string[] ToList, string[]? CCList = null, string[]? BCCList = null) { return new MailObject(this, Subject, Body, Priority, HTML, ToList, CCList, BCCList); } + /// + /// 发送邮件 + /// + /// + /// public MailSendResult Send(MailObject Mail) { _LastestResult = MailManager.Send(this, Mail, out _ErrorMsg); @@ -36,12 +80,19 @@ namespace Milimoe.FunGame.Core.Api.Transmittal private bool IsDisposed = false; + /// + /// 关闭邮件服务 + /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } + /// + /// 关闭邮件服务 + /// + /// protected void Dispose(bool Disposing) { if (!IsDisposed) diff --git a/Library/Common/Network/MailObject.cs b/Library/Common/Network/MailObject.cs index 71819ee..0fc6941 100644 --- a/Library/Common/Network/MailObject.cs +++ b/Library/Common/Network/MailObject.cs @@ -1,20 +1,127 @@ using System.Net.Mail; using Milimoe.FunGame.Core.Api.Transmittal; +using Milimoe.FunGame.Core.Library.Constant; namespace Milimoe.FunGame.Core.Library.Common.Network { public class MailObject { + /// + /// 发件人邮箱 + /// public string Sender { get; } = ""; - public string SenderName { get; } = ""; - public string Subject { get; } = ""; - public string Body { get; } = ""; - public MailPriority Priority { get; } = MailPriority.Normal; - public bool HTML { get; } = false; - public string[] ToList { get; } = Array.Empty(); - public string[]? CCList { get; } = Array.Empty(); - public string[]? BCCList { get; } = Array.Empty(); + /// + /// 发件人名称 + /// + public string SenderName { get; } = ""; + + /// + /// 邮件主题 + /// + public string Subject { get; } = ""; + + /// + /// 邮件内容 + /// + public string Body { get; } = ""; + + /// + /// 邮件优先级 + /// + public MailPriority Priority { get; } = MailPriority.Normal; + + /// + /// 内容是否支持HTML + /// + public bool HTML { get; } = true; + + /// + /// 收件人列表 + /// + public List ToList { get; } = new(); + + /// + /// 抄送列表 + /// + public List CCList { get; } = new(); + + /// + /// 密送列表 + /// + public List BCCList { get; } = new(); + + public MailObject() + { + + } + + /// + /// 使用MailSender工具类创建邮件对象 + /// + /// + public MailObject(MailSender Sender) + { + this.Sender = Sender.SmtpClientInfo.SenderMailAddress; + this.SenderName = Sender.SmtpClientInfo.SenderName; + } + + /// + /// 使用地址和名称创建邮件对象 + /// + /// + /// + public MailObject(string Sender, string SenderName) + { + this.Sender = Sender; + this.SenderName = SenderName; + } + + /// + /// 使用地址和名称创建邮件对象,同时写主题、内容、单个收件人 + /// + /// + /// + /// + /// + public MailObject(MailSender Sender, string Subject, string Body, string To) + { + this.Sender = Sender.SmtpClientInfo.SenderMailAddress; + this.SenderName = Sender.SmtpClientInfo.SenderName; + this.Subject = Subject; + this.Body = Body; + ToList.Add(To); + } + + /// + /// 使用地址和名称创建邮件对象,同时写主题、内容、单个收件人、单个抄送 + /// + /// + /// + /// + /// + /// + public MailObject(MailSender Sender, string Subject, string Body, string To, string CC) + { + this.Sender = Sender.SmtpClientInfo.SenderMailAddress; + this.SenderName = Sender.SmtpClientInfo.SenderName; + this.Subject = Subject; + this.Body = Body; + ToList.Add(To); + CCList.Add(CC); + } + + /// + /// 完整的创建邮件对象 + /// + /// + /// + /// + /// + /// + /// + /// + /// public MailObject(MailSender Sender, string Subject, string Body, MailPriority Priority, bool HTML, string[] ToList, string[]? CCList = null, string[]? BCCList = null) { this.Sender = Sender.SmtpClientInfo.SenderMailAddress; @@ -23,9 +130,74 @@ namespace Milimoe.FunGame.Core.Library.Common.Network this.Body = Body; this.Priority = Priority; this.HTML = HTML; - this.ToList = ToList; - this.CCList = CCList; - this.BCCList = BCCList; + AddTo(ToList); + if (CCList != null) AddCC(CCList); + if (BCCList != null) AddBCC(BCCList); + } + + /// + /// 发送邮件 + /// -- 适合创建一次性邮件并发送 -- + /// + /// + /// + public MailSendResult Send(MailSender sender) + { + return sender.Send(this); + } + + /// + /// 添加收件人 + /// + /// + public void AddTo(string to) + { + if (!ToList.Contains(to)) ToList.Add(to); + } + + /// + /// 添加多个收件人 + /// + /// + public void AddTo(params string[] to) + { + foreach (string t in to) AddTo(t); + } + + /// + /// 添加抄送 + /// + /// + public void AddCC(string cc) + { + if (!CCList.Contains(cc)) CCList.Add(cc); + } + + /// + /// 添加多个抄送 + /// + /// + public void AddCC(params string[] cc) + { + foreach (string c in cc) AddCC(c); + } + + /// + /// 添加密送 + /// + /// + public void AddBCC(string bcc) + { + if (!BCCList.Contains(bcc)) BCCList.Add(bcc); + } + + /// + /// 添加多个密送 + /// + /// + public void AddBCC(params string[] bcc) + { + foreach (string b in bcc) AddBCC(b); } } } diff --git a/Service/MailManager.cs b/Service/MailManager.cs index 7078d6b..89e542b 100644 --- a/Service/MailManager.cs +++ b/Service/MailManager.cs @@ -1,5 +1,4 @@ -using System.Collections; -using System.Net; +using System.Net; using System.Net.Mail; using Milimoe.FunGame.Core.Api.Transmittal; using Milimoe.FunGame.Core.Library.Common.Architecture; @@ -11,8 +10,39 @@ namespace Milimoe.FunGame.Core.Service { internal class MailManager { - internal static Hashtable HashClient { get; } = new Hashtable(); + /// + /// 用于保存Smtp客户端 + /// 一个邮件服务对应一个Smtp客户端 + /// + internal static Dictionary SmtpClients { get; } = new(); + + /// + /// 用于保存邮件服务 + /// 允许服务器同时存在多个服务 + /// + internal static Dictionary MailSenders { get; } = new(); + /// + /// 获取某个已经保存过的邮件服务 + /// + /// + /// + internal static MailSender? GetSender(Guid MailSenderID) + { + if (MailSenders.TryGetValue(MailSenderID, out MailSender? value)) + { + return value; + } + return null; + } + + /// + /// 统一调用此方法发送邮件 + /// + /// + /// + /// + /// internal static MailSendResult Send(MailSender Sender, MailObject Mail, out string ErrorMsg) { ErrorMsg = ""; @@ -21,7 +51,7 @@ namespace Milimoe.FunGame.Core.Service SmtpClientInfo Info = Sender.SmtpClientInfo; SmtpClient Smtp; Guid MailSenderID = Sender.MailSenderID; - if (!HashClient.ContainsKey(MailSenderID)) + if (!SmtpClients.ContainsKey(MailSenderID)) { Smtp = new() { @@ -31,9 +61,9 @@ namespace Milimoe.FunGame.Core.Service DeliveryMethod = SmtpDeliveryMethod.Network, Credentials = new NetworkCredential(Info.SenderMailAddress, Info.SenderPassword) }; - HashClient.Add(MailSenderID, Smtp); + SmtpClients.Add(MailSenderID, Smtp); } - else Smtp = (SmtpClient)HashClient[MailSenderID]!; + else Smtp = SmtpClients[MailSenderID]; MailMessage Msg = new() { Subject = Mail.Subject, @@ -48,19 +78,13 @@ namespace Milimoe.FunGame.Core.Service { if (To.Trim() != "") Msg.To.Add(To); } - if (Mail.CCList != null) + foreach (string CC in Mail.CCList) { - foreach (string CC in Mail.CCList) - { - if (CC.Trim() != "") Msg.CC.Add(CC); - } + if (CC.Trim() != "") Msg.CC.Add(CC); } - if (Mail.BCCList != null) + foreach (string BCC in Mail.BCCList) { - foreach (string BCC in Mail.BCCList) - { - if (BCC.Trim() != "") Msg.Bcc.Add(BCC); - } + if (BCC.Trim() != "") Msg.Bcc.Add(BCC); } Smtp.SendMailAsync(Msg); return MailSendResult.Success; @@ -72,15 +96,21 @@ namespace Milimoe.FunGame.Core.Service } } + /// + /// 关闭邮件服务 + /// + /// + /// internal static bool Dispose(MailSender Sender) { try { Guid MailSenderID = Sender.MailSenderID; - if (HashClient.ContainsKey(MailSenderID)) + if (SmtpClients.TryGetValue(MailSenderID, out SmtpClient? value)) { - ((SmtpClient)HashClient[MailSenderID]!).Dispose(); - HashClient.Remove(MailSenderID); + value.Dispose(); + SmtpClients.Remove(MailSenderID); + MailSenders.Remove(MailSenderID); return true; } return false;