Created
July 29, 2023 20:23
-
-
Save promontis/9835d43872d6f8fd964d6bbce5442628 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class EmailAddress | |
{ | |
public string Email { get; set; } | |
public string Name { get; set; } | |
} | |
public delegate Task EventHandler<TEvent>(dynamic templateData, TEvent @event, Dictionary<string, object> parameters); | |
public interface IMailAppender : IMailInterceptor | |
{ | |
Task Append(Mail mail, Dictionary<string, object> parameters); | |
} | |
public interface IMailClient | |
{ | |
Task SendMail(Mail mail); | |
} | |
public interface IMailInterceptor | |
{ | |
bool Matches(string templateId, MailType type, Dictionary<string, object> parameters); | |
} | |
public interface IPublishMailCompositionEvents | |
{ | |
void Subscribe<TEvent>(EventHandler<TEvent> handler); | |
} | |
public interface ISubscribeToMailCompositionEvents : IMailInterceptor | |
{ | |
void Subscribe(IPublishMailCompositionEvents publisher); | |
} | |
public class Mail: IPublishMailCompositionEvents | |
{ | |
private readonly IDictionary<Type, List<EventHandler<object>>> _subscriptions = | |
new Dictionary<Type, List<EventHandler<object>>>(); | |
public List<EmailAddress> Tos { get; set; } | |
public List<EmailAddress> Ccs { get; set; } | |
public List<EmailAddress> Bccs { get; set; } | |
public EmailAddress From { get; set; } | |
public EmailAddress ReplyTo { get; set; } | |
public string Subject { get; set; } | |
public List<string> Categories { get; set; } | |
public List<MailAttachment> Attachments { get; set; } | |
public string TemplateId { get; } | |
public dynamic TemplateData { get; set; } | |
public MailType Type { get; } | |
public Mail(string templateId, MailType type) | |
{ | |
TemplateId = templateId; | |
Type = type; | |
Tos = new List<EmailAddress>(); | |
Ccs = new List<EmailAddress>(); | |
Bccs = new List<EmailAddress>(); | |
Attachments = new List<MailAttachment>(); | |
Categories = new List<string>(); | |
} | |
public void Subscribe<TEvent>(EventHandler<TEvent> handler) | |
{ | |
if (!_subscriptions.TryGetValue(typeof(TEvent), out var handlers)) | |
{ | |
handlers = new List<EventHandler<object>>(); | |
_subscriptions.Add(typeof(TEvent), handlers); | |
} | |
handlers.Add((mail, @event, parameters) => handler(mail, (TEvent)@event, parameters)); | |
} | |
public void ClearSubscriptions() => _subscriptions.Clear(); | |
} | |
public class MailCompositionHandler | |
{ | |
private readonly IEnumerable<IMailInterceptor> _interceptors; | |
public MailCompositionHandler(IEnumerable<IMailInterceptor> interceptors) | |
{ | |
_interceptors = interceptors; | |
} | |
public async Task<Mail> Handle(string templateId, MailType type, Dictionary<string, object> parameters) | |
{ | |
var mail = new Mail(templateId, type); | |
var interceptors = _interceptors | |
.Where(interceptor => interceptor.Matches(templateId, type, parameters)) | |
.ToList(); | |
try | |
{ | |
foreach (var subscriber in interceptors.OfType<ISubscribeToMailCompositionEvents>()) | |
{ | |
subscriber.Subscribe(mail); | |
} | |
var pendingTasks = new List<Task>(); | |
foreach (var appender in interceptors.OfType<IMailAppender>()) | |
{ | |
pendingTasks.Add(appender.Append(mail, parameters)); | |
} | |
await Task.WhenAll(pendingTasks); | |
return mail; | |
} | |
finally | |
{ | |
mail.ClearSubscriptions(); | |
} | |
} | |
} | |
public enum MailType | |
{ | |
Transactional, | |
Marketing | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment