Per un semplice esempio, supponi che la tua applicazione invii notifiche agli utenti quando accadono vari eventi. Quindi nel database potrei avere le seguenti tabelle:
TABLE Event
EventId uniqueidentifier
EventName varchar
TABLE User
UserId uniqueidentifier
Name varchar
TABLE EventSubscription
EventUserId
EventId
UserId
Gli eventi stessi sono generati dal programma. Pertanto, nell'applicazione sono presenti punti codificati in cui viene generata un'istanza dell'evento e devono essere notificati a tutti gli utenti iscritti.
Pertanto, l'applicazione stessa non modifica la tabella Event
, tranne durante l'installazione iniziale e durante un aggiornamento in cui potrebbe essere creata una nuova Event
.
Ad un certo punto, quando viene generato un evento, l'applicazione deve cercare Event
e ottenere un elenco di User
s. Qual è il modo migliore per collegare l'evento nel codice sorgente all'evento nel database?
Opzione 1:
Memorizza EventName
nel programma come costante fissa e cerca il nome.
Opzione 2:
Memorizza EventId
nel programma come Guid
statico, e cerca per ID.
Credito extra
In altre circostanze simili, potrei voler includere un comportamento personalizzato con il tipo di evento. Cioè, voglio sottoclassi della mia classe di entità Event
con comportamenti diversi, e quando cerco un evento, voglio che restituisca un'istanza della mia sottoclasse.
Ad esempio:
class Event
{
public Guid Id { get; }
public Guid EventName { get; }
public ReadOnlyCollection<EventSubscription> EventSubscriptions { get; }
public void NotifySubscribers()
{
foreach(var eventSubscription in EventSubscriptions)
{
eventSubscription.Notify();
}
this.OnSubscribersNotified();
}
public virtual void OnSubscribersNotified() {}
}
class WakingEvent : Event
{
private readonly IWaker waker;
public WakingEvent(IWaker waker)
{
if(waker == null) throw new ArgumentNullException("waker");
this.waker = waker;
}
public override void OnSubscribersNotified()
{
this.waker.Wake();
base.OnSubscribersNotified();
}
}
Quindi, questo significa che devo mappare WakingEvent
a qualsiasi chiave che sto usando per cercarlo nel database. Diciamo che è il EventId
. Dove immagazzino questa relazione? Va nella classe di repository degli eventi? Il WakingEvent
conosciuto dovrebbe dichiarare il proprio ID in un membro statico o in un metodo?
... e poi, è tutto indietro? Se tutti gli eventi hanno una sottoclasse, invece di recuperare gli eventi per ID, dovrei chiedere al mio repository il WakingEvent
come questo:
public T GetEvent<T>() where T : Event
{
... // what goes here?
}
Non posso essere il primo ad affrontarlo. Qual è la migliore pratica?