I am building an app (.NET, but whatever) which is supposed to be able to send notifications to users.
Each Notification
can either be a Reminder
or a Newsletter
, and I'll possibly add more types in the future. Each type is handled differently. Reminders are periodical, so I need to keep track of who is reminded of what, while newsletter is just broadcasted with each publish to all users.
Additionally, I can send notifications using any of several notification mediums or however you want to call those (Email
, Push
etc.). Those are modeled in the domain something like this:
public class Email
{
public string Sender { get; set; }
public string Recipient { get; set; } // email address on the user object
public string Subject { get; set; }
public string Body { get; set; }
}
public class Push
{
public string Title { get; set; }
public string Content { get; set; }
public string DeviceId { get; set; } // some token on the user object
}
I'll most likely add more NotificationMedium
types in the future as well.
So, each concrete notification can be of just one concrete NotificationType
and can be sent via one or many NotificationMediums
, with both evolving in variety independently.
I already have an IEmailSender
and an IPushSender
, both being implemented by concrete senders relying on specific third party services, and receiving one of those domain objects from above.
My first thought was to implement a Bridge Pattern, but I'm not really sure how that would work. I'm mostly insecure about how I'd unify Email
, Push
and other "mediums", since they do vary in detail (Push
doesn't have a sender
, and I don't want to make something rely on things it doesn't need).
I'm also pretty sure that each Notification
must have its type stored in the database, maybe have some NotificationType
table or even an enum
. But this would mean that I'd have to have some way of converting a Notification
to EmailNotification
or PushNotification
in the end, which would completely defeat the purpose of the Bridge Pattern.
What I'd like is to have a mechanism which recieves a Notification
, handles it internally based on its NotificationType
, and then send it off via one or more predefined NotificationMediums
, which I could add or remove without needing to affect anything but the class that brings all of these concepts together.
P.S. The class that brings all of these concepts together will most probably be a CQRS Command Handler
, since I'm already using MediatR
in my project. I look at it as a kind of "composition root" for this use case, so I don't believe that changes anything in the big picture, but I though I'd state it just in case.
Any suggestions with this?
ISender
. Both senders have apublic void
method, but the inputs aren't the same. Somehing likeIEmailSender.Send(Email message)
andIPushSender.Send(Push message)
. Email sending requires four parameters (sender - from config, recipient - fromUser
and subject/body - fromNotification
). Push is similar, but without the sender.Email
andPush
types (so things like Body, Content, possibly Title), let the object popped from the queue supply it. 1/2