Reputation: 938
I need plan for build Notifications/Alerts system.
I have object named "Campaign" and it have "Status". Status can be Accepted, Rejected, Supplement, Work and others. I want send Notifications/Alerts when the Status change.
E.q. e-mail notification and alert in my portal.
I don't want make it all in one controller where I operate on Campaign. So I was thinking about Delegates and Events. But in last I don't know enought to do it.
What I thinking about:
Domain model:
class Campaign {
CampaignStatus Status { get; set;}
}
abstract class Notification {
// properties
}
class EmailNotification {
// properties specific for email
}
class Alert {
// properties specific for alerts
}
class CampaignAlert {
// properties specific for campaign alerts
}
Services:
INotificationsService {
Send();
}
IAlertsService : INotificationsService {
Get(); // I need showing list of alerts too
GetAll();
Update(); // for updating info if alert was viewed.
Save(); // I need saving alerts in db.
}
And how I can do it with events? So much automatic as can. Ofcourse I can manualy call the AlertsService and make alert. But this is bad ;)
I was thinking about adding delegate and event to Campaign.
class Campaign {
public delegate void CampaignStatusChange(object sender, EventArgs e);
public event CampaignStatusChange OnCampaignStatusChange;
}
And connect event with:
class CampaignStatusChangeHandler {
public CampaignStatusChangeHandler(IRepository<bla bla> repository, INotificationsService notificationService) {
// these will be inject via ctor
}
//
}
I want made it as much as I can with SOLID, KISS, and DRY. Ofcourse with TDD and I using IoC to inject objects ;)
Summary I need notification service that I can indepentend send emails and alerts. I need display alerts on frontend.
My alert domain model like that:
public abstract class Notification
{
public string Title { get; set; }
public string Content { get; set; }
public DateTime Created { get; set; }
public NotificationType Type { get; set; }
}
public enum NotificationType
{
Email,
Alert
}
public class EmailNotification : Notification
{
public string From { get; set; }
public ICollection<string> To { get; set; }
public ICollection<string> Bcc { get; set; }
}
public class Alert : Notification
{
public object LinkedObject { get; set; }
public bool WasSeen { get; set; }
}
public class CampaignAlert : Alert
{
public CampaignAlertType CampaignAlertType { get; set; }
}
public enum CampaignAlertType
{
Accepted,
Rejected,
Active,
Finished
}
When I want to send Alert to user I want send email sometimes and alert. Sometimes I want send only email and only alert.
Upvotes: 5
Views: 8325
Reputation: 44600
I wouldn't use delegates and events here. Calling a method is much more transparent and you wouldn't have any benefits of using delegates and events.
My structure would look like that:
interface ICampaignService
{
// It's business logic
// 1. Updates campaign
// 2. Creates notification using builder
// 3. Uses notification sender to send notification
// (4. creates alert object for notification)
void UpdateCampaignStatus(int campaignId, Status status);
}
// Builds different notifications based on different
// campaign statuses. For instance assign different
// email templates and use different text.
interface INotificationBuilder<TNotification> where TNotification : Notification
{
TNotification Build();
}
interface INotificationSender
{
Send(Notification notification);
}
interface IAlertsRepository
{
Get();
GetAll();
Update();
Create();
}
Also possible (if there are different types of notifications)
// If you want to send different types of notifications like
// Email, Push, SMS etc. Each notification type requires different
// logic for sending notification. Strategy pattern is perfect here.
interface INotificationStrategy : INotificationSender
{
Send(Notification notification);
}
It's all depends on your application extensibility requirements. SOLID is very important, but make sure to avoid over-engineering (you mentioned KISS :)).
Upvotes: 5