【发布时间】:2020-12-20 22:55:55
【问题描述】:
嗨,SO 的好朋友们!
这更像是一个设计问题,所以我将进入一个详细的示例。
让我解释一下我们发送电子邮件的方式。
在应用程序的各个部分,我们在Notification 表中为我们可能需要发送的不同类型的电子邮件创建条目。
例如:NotificationQueue 表如下所示:
NotificationQueueID OrderID EmailType Notes SentDatetime
1 461196 OrderUpdate SomeNote1 2020-09-01 14:45:13.153
2 461194 OrderCancellation SomeNote2 2020-09-01 14:45:13.153
使用 DbContext 中的属性访问它:
public DbSet<NotificationQueue> NotificationQueues { get; set; }
不同类型的电子邮件在enum 中建模:
public enum TypeOfEmail
{
OrderCancellation,
OrderUpdate
}
我们有一个 EmailModel 类,它有一个 TicketsInNotificationQueue 属性,其中包含我们拥有的任何电子邮件类型的列表。例如:在任何给定时间,它都可以有UpdatedTickets 或CancelledTickets 的列表。电子邮件类型说明TicketsInNotificationQueue 属性中的票证类型。
public class EmailModel
{
public EmailModel(TypeOfEmail emailType, TicketsInNotificationQueue ticketsInNotificationQueue)
{
EmailType = emailType;
TicketsInNotificationQueue = ticketsInNotificationQueue;
}
public TypeOfEmail EmailType { get; set; }
public TicketsInNotificationQueue TicketsInNotificationQueue { get; set; }
}
public class TicketsInNotificationQueue
{
public List<OrderCancellation> CancelledTickets { get; set; }
public List<OrderUpdate> UpdatedTickets { get; set; }
}
public class OrderCancellation : CommonOrderInformation
{
public string SomeOrderId { get; set; }
}
public class OrderUpdate: CommonOrderInformation
{
public string SomeUpdateRelatedProperty { get; set; }
}
public class CommonOrderInformation
{
public int NotificationQueueId { get; set; }
public string ReferenceNumber { get; set; }
}
有一种方法可以从Notification 表中检索票证:
public async Task<TicketsInNotificationQueue> GetTicketsfromNotificationQueueAsync(TypeOfEmail emailType)
{
var ticketsInNotificationQueue = new TicketsInNotificationQueue();
using (var dbCon = GetSomeDbContext())
{
var notifications = dbCon.NotificationQueues.Where(x => x.EmailType == emailType.ToString()).ToList();
foreach (var ntf in notifications)
{
if (ntf.EmailType == TypeOfEmail.OrderCancellation.ToString())
{
if (ticketsInNotificationQueue.CancelledTickets == null)
{
ticketsInNotificationQueue.CancelledTickets = new List<OrderCancellation>();
}
ticketsInNotificationQueue.CancelledTickets.Add(new OrderCancellation()
{
NotificationQueueId = ntf.NotificationQueueID,
ReferenceNumber = ntf.OrderID,
SomeOrderId = "Something from a table."
});
}
else if (ntf.EmailType == TypeOfEmail.OrderUpdate.ToString())
{
if (ticketsInNotificationQueue.UpdatedTickets == null)
{
ticketsInNotificationQueue.UpdatedTickets = new List<OrderUpdate>();
}
var notes = dbCon.NotificationQueues.FirstOrDefault(x => x.NotificationQueueID == ntf.NotificationQueueID)?.Notes;
ticketsInNotificationQueue.UpdatedTickets.Add(new OrderUpdate()
{
NotificationQueueId = ntf.NotificationQueueID,
ReferenceNumber = ntf.OrderID,
SomeUpdateRelatedProperty = "Something from a table."
});
}
}
}
return ticketsInNotificationQueue;
}
现在我只需要这个列表,并根据我刚刚收到的票的类型过滤掉notificationIds,然后继续处理它们。 (通知发送后我需要那些notificationIds 来设置SentDatetime)。
var ticketsReceived = false;
notificationIds = new List<int>();
if (ticketsInNotificationQueue.CancelledTickets != null && ticketsInNotificationQueue.CancelledTickets.Any())
{
ticketsReceived = true;
notificationIds = ticketsInNotificationQueue.CancelledTickets.Select(x => x.NotificationQueueId).ToList();
}
else if (ticketsInNotificationQueue.UpdatedTickets != null && ticketsInNotificationQueue.UpdatedTickets.Any())
{
ticketsReceived = true;
notificationIds = ticketsInNotificationQueue.UpdatedTickets.Select(x => x.NotificationQueueId).ToList();
}
if (ticketsReceived)
{
// Proceed with the process of sending the email, and setting the `SentDateTime`
}
我在这里看到的问题是,随着emails 的类型变大,比如说10-20,检索票证并稍后过滤掉票证的方法需要增长得如此之大,以至于它会失控我根本不喜欢的可读性和代码可管理性方面。我需要检查获取中请求的emailType 以及已收到emailType 的部分(以获取SentDateTime 更新的相应notificationIds)。
那么有没有其他方法来设计这个工作流程(我什至愿意使用反射等)以使其更易于管理和简洁?
任何帮助将不胜感激!
【问题讨论】:
标签: c# asp.net asp.net-mvc email architecture