콘텐츠 제공 업체가있는 추상화 된 이메일 발신자
이메일 콘텐츠 제공 업체와 함께 이메일 발신자를 만들었으며 이메일 유형에 따라 변경됩니다. 개선하려면 도움이 필요합니다.
이 두 모델은
public class EmailAddress
{
public string Name { get; set; }
public string Address { get; set; }
}
public class EmailMessage
{
public EmailMessage()
{
ToAddresses = new List<EmailAddress>();
CcAddresses = new List<EmailAddress>();
}
public List<EmailAddress> ToAddresses { get; set; }
public List<EmailAddress> CcAddresses { get; set; }
public string Subject { get; set; }
public string Content { get; set; }
}
콘텐츠 제공자는 모든 이메일 정보 (제목, 본문,받는 사람 및 참조)를 제공합니다.
public interface IEmailContentProvider
{
EmailMessage Message { get; }
}
그런 다음 매개 변수를 사용 하여 이메일 정보를 가져 오는 IEmailSender
단일 메소드 가있는 추상화 된 이메일 발신자 가 있습니다.Send
IEmailContentProvider
interface IEmailSender
{
Task Send(IEmailContentProvider provider);
}
콘텐츠 제공 업체에 대한 예가 있습니다. WelcomEmailProvider
public class WelcomEmailProvider : IEmailProvider
{
public EmailMessage Message { get; }
public WelcomEmailProvider(string address, string name)
{
Message = new EmailMessage
{
Subject = $"Welcome {name}", Content = $"This is welcome email provider!",
ToAddresses = new List<EmailAddress> { new EmailAddress { Address = address, Name = name} }
};
}
}
IEmailSender
구현 :
public class EmailSender : IEmailSender
{
private readonly SmtpOptions _options;
public EmailSender(IOptions<SmtpOptions> options)
{
_options = options.Value;
}
public async Task Send(IEmailContentProvider provider)
{
var emailMessage = provider.Message;
var message = new MimeMessage();
message.From.Add(new MailboxAddress(_options.Sender.Name, _options.Sender.Address));
message.To.AddRange(emailMessage.ToAddresses.Select(x => new MailboxAddress(x.Name, x.Address)));
message.Cc.AddRange(emailMessage.CcAddresses.Select(x => new MailboxAddress(x.Name, x.Address)));
message.Subject = emailMessage.Subject;
message.Body = new TextPart(TextFormat.Html) { Text = emailMessage.Content };
using var emailClient = new SmtpClient();
await emailClient.ConnectAsync(_options.Server, _options.Port, _options.EnableSsl);
await AuthenticatedData(emailClient);
await emailClient.SendAsync(message);
await emailClient.DisconnectAsync(true);
}
private async Task AuthenticatedData(SmtpClient smtpClient)
{
if (string.IsNullOrWhiteSpace(_options.Username) || string.IsNullOrWhiteSpace(_options.Password))
return;
emailClient.AuthenticationMechanisms.Remove("XOAUTH2");
await emailClient.AuthenticateAsync(_options.Username, _options.Password);
}
}
그리고 여기에 그것을 사용하고 이메일을 보내는 방법이 있습니다.
class Sample
{
private readonly IEmailSender _emailSender;
public Samole(IEmailSender emailSender)
{
_emailSender = emailSender;
}
public async Task DoSomethingThenSendEmail()
{
await _emailSender.Send(new WelcomEmailProvider("[email protected]", "Someone"));
}
}
답변
public EmailMessage()
{
ToAddresses = new List<EmailAddress>();
CcAddresses = new List<EmailAddress>();
}
필요하지 않지만을 시작하면 이해할 수 ToAddress
있지만 이와 같이 목록을 시작하면 많은 메모리가 소모 될 수 있습니다 (많은 양의 EmailMessage
인스턴스 가 있다고 상상해보세요 ! 따라서이를 null로 유지하고 null
유효성 검사를 사용 하여 강제로 필요할 때 시작합니다 (예 : 보낸 사람).
전반적인 디자인은 충분하지만 직접 할 수 있습니다.
public class EmailMessage
{
public EmailAddress From { get; set; }
public IEnumerable<EmailAddress> To { get; set; }
public IEnumerable<EmailAddress> Cc { get; set; }
public IEnumerable<EmailAddress> Bcc { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
}
public interface IEmailProvider
{
IEmailServerSetting ServerSettings { get; set; }
}
EmailMessage
메시지의 전체 모델로 From (필수), To (필수), CC (선택), BCC (선택), Subject 및 Body를 포함해야합니다. 그 이유는 모든 메시지에 대한 요구 사항으로 항상 함께 쌍을 이루고 나중에 데이터베이스 측에서 구현하는 것이 더 쉬울 것이기 때문입니다. using IEnumerable<EmailAddress>
은 IEnumerable
. 따라서 List
.
대한 IEmailProvider
이메일 제공 업체는 요구 사항으로 자신의 설정을 포함해야한다. 이렇게하면 각 이메일 메시지에 고유 한 설정이 포함되어있어 작업이 더 쉬워집니다. 이렇게하면 별도의 코딩없이 여러 제공 업체에서 여러 이메일을 보낼 수 있습니다. IOptions
독립적으로 처리되지만 실제로 IOptions
는 그 자체로는 유용하지 않으며에서만 사용 EmailProvider
되므로 계약에 추가하면 항상 인터페이스로 구현됩니다. 이렇게하면 공급자가 항상 있다 IOptions
. 게다가, 주요 구현과 관련 되거나 IOptions
유사한 이름으로 변경되어야합니다 . 이것은 옵션이 아니라 설정이기 때문입니다. 텍스트 또는 html로 보내기, 첨부 파일, 그림 등을 비활성화 / 활성화하는 등 관리 할 수있는 이메일 선택적 설정 및 기능을 처리하는 데 사용 합니다.EmailServerSetting
EmailProviderSetting
IOptions
또한 일을 마무리하기 위해 미들웨어 클래스가 필요하고 SmtpClient
. 이것은 현재 작업의 유연성을 증가 당신에게 이점을 제공하고 코드를 재사용하기 위해 쉽게와 함께 한 지붕 아래에서 일을을 마무리 것이다 (예 MimeMessage
, TextPart
.. 등.) 대신에 각각의 새로운 보낸 사람에 재 구현을의. 또한 그렇게 멀리 갈 경우 여러 공급자를 저장할 컬렉션을 만들 수 있습니다. 또한 새 공급자를 추가하고, 이들을 처리하고, 메시지를 처리하고, 작업 범위를 유지할 수 있습니다.
최종 사용법을 상상하는 방법은 다음과 같습니다.
새 공급자 만들기 :
// creating a new email provider
public class SomeEmailProvider : IEmailProvider
{
// only set the settings internally but it's exposed to be readonly
public EmailServerSetting ServerSettings { get; private set; }
public SomeEmailProvider()
{
//set up the server settings
ServerSettings = new EmailServerSetting
{
ServerType = EmailServerType.POP,
Server = "pop.mail.com",
Port = 995,
Encryption = EmailServerEncryption.SSLOrTLS,
EnableSsl = true
};
}
// some other related code
}
이제 새 메일 메시지를 만들고 보냅니다.
// can be single object or collection
var messages = new EmailMessage
{
From = new EmailAddress("Test", "[email protected]"),
To = new EmailAddress [] {
new EmailAddress("Test1", "[email protected]"),
new EmailAddress("Test2", "[email protected]")
},
Subject = "Testing Subject",
Body = "Normal Text Body"
};
using(var client = new EmailClient(new SomeEmailProvider()))
{
client.Options = new EmailClientOptions
{
// would send it as plain text
EnableHtml = false
};
client.Messages.Add(messages);
client.Send();
}