Design – Best design pattern for Notification System => How to handle multiple languages and items

designdesign-patternspatterns-and-practicesprogramming practices

As always I came here to ask for some light in a design issue I am facing.

I have a system that issues some notifications :

  • PackageReceivedNotification
  • PackageSentNotification
  • DisccountAvailableNotification
  • More in the future

I want to store the text of them in the DB in multiple languages (imagine english and spanish)

Each notification has a method that returns a formatted representation of the notification by mixing a base text (retrieved from DB) and some information retrieved from the object associated to each notification:

public interface INotification
{
    string GetMessageToSend(string languageCode);
}

//Example of implementation
public class DisccountAvailableNotification:INotification
{
    Disccount Disccount{get; private set;}
    Dictionary<string,string> TranslatedNotificationTexts{get; private set;}
    public DisccountAvailableNotification(Disscount disccount)
    {
       Disccount = disccount;
       TranslatedNotificationTexts= getFromDatabase();
    }
    public string GetMessageToSend(string languageCode)
    {
         //Retrieved from database imagine :"{0} has a discount of {1}"
         string translatedNotText= TranslatedNotificationTexts[languageCode]

         return string.Format(translatedNotText, Disccount.name, Disccount.percentage);
    }
}

I think that a design of code that allows me to newing Notification passing as parameter in the constructor the concrete type of class that it is associated, for example a

  1. DisccountAvailableNotification needs a Disccount instance for being generated
  2. PackageSentNotification needs a Package instance for being generated

My desirable code will be a "generic" notificacionprovider that allows me to generate INotifications but be compiler safe, so its smart enough to tell me which type of objet it needs to create the notification , something like this:

INotification notification1= NotificationProvider
    .GenerateNotification<DisccountNotification>.(new Disccount("90%"));

INotification notification2= NotificationProvider
    .GenerateNotification<PackageSentNotification>(new Package("Socks","19$"));

Will be that possible with a flexible design that allows new types of notifications in the future without too many changes?
Which would be the best design-approach?

Best Answer

Ideally you would have a method which takes one generic parameter explicitly and infers the other, which I don't think is directly possible in C#, although I'd love to be wrong on that.

If you don't mind a less pretty interface, you can do it fairly simply:

public interface IProvidedNotification<T> : INotification
{
    void Initialize(T data);
}

public interface INotificationProvider
{
    INotification GenerateNotification<TN, TD>(TD data) where TN : IProvidedNotification<TD>;
}

But you would have to call it with both parameters:

var note = NotificationProvider.GenerateNotification<PackageSentNotification,Package>(new Package("Socks","19$"));
Related Topic