Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Notification system/service in C# with ASP.NET MVC

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.

like image 454
Nerf Avatar asked Jul 13 '16 18:07

Nerf


1 Answers

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 :)).

like image 185
Andrei Avatar answered Oct 17 '22 02:10

Andrei