Domanda

Sto cercando di vedere quali approcci le persone potrebbero aver adottato per rilevare i cambiamenti nelle entità che fanno parte dei loro aggregati. Ho qualcosa che funziona, ma non ne vado matto. Fondamentalmente, il mio repository è responsabile per determinare se lo stato di una radice aggregata è cambiato. Supponiamo che io abbia una radice aggregata chiamata Book e un'entità chiamata Page all'interno dell'aggregato. Un Libro contiene una o più entità Pagina , memorizzate in una raccolta Pagine .

Principalmente, gli scenari insert vs. update vengono eseguiti ispezionando la radice aggregata e le sue entità per determinare la presenza di una chiave. Se la chiave è presente, si presume che l'oggetto sia stato, una volta, salvato nell'origine dati sottostante. Questo lo rende un candidato per un aggiornamento; ma non è definitivo in base a quello solo per le entità. Con la radice aggregata la risposta è ovvia, poiché ce n'è solo una ed è il punto di ingresso singolare, si può presumere che la presenza chiave determinerà l'operazione. È uno scenario accettabile, nel mio caso, salvare nuovamente la radice aggregata stessa in modo da poter acquisire una data di modifica.

Per facilitare questo comportamento per le entità stesse, la mia classe EntityBase contiene due proprietà semplici: IsUpdated () , IsDeleted () . Entrambi questi valori predefiniti sono false. Non ho bisogno di sapere se è nuovo o no, perché posso fare quella determinazione in base alla presenza della chiave, come accennato in precedenza. I metodi sull'implementazione, in questo caso la Pagina, avrebbero ciascun metodo che modifica il set di dati di supporto IsUpdated () su true.

Ad esempio, Page ha un metodo chiamato UpdateSectionName () che modifica il valore di supporto della proprietà SectionName , che è di sola lettura. Questo approccio viene utilizzato in modo coerente, in quanto consente un punto di attacco logico dei validatori nel metodo (che impedisce all'entità di entrare in uno stato non valido) che esegue tale impostazione di dati. Il risultato finale è che devo mettere un this.IsUpdated () = true; alla fine del metodo.

Quando la radice aggregata viene inviata nel repository per Save () (un interruttore logico su Insert () o Update () operazione), può quindi scorrere la raccolta Pagine nel Libro , cercando tutte le pagine che presentano uno dei tre scenari:

  1. Nessuna chiave. Verrà inserita una pagina senza chiave.
  2. IsDeleted = true; Un'eliminazione supera un aggiornamento e la cancellazione verrà impegnata, ignorando qualsiasi aggiornamento per la Pagina .
  3. IsUpdated = true; Verrà eseguito un aggiornamento per la Pagina.

Farlo in questo modo mi impedisce di aggiornare ciecamente tutto ciò che è nella raccolta Pagine, il che potrebbe essere scoraggiante se ci fossero diverse centinaia di entità Pagina nel Libro, per esempio. Avevo pensato di recuperare una copia del libro, di fare un confronto e di confermare solo le modifiche rilevate (inserimenti, aggiornamenti ed eliminazioni basate sulla presenza e / o sul confronto), ma sembrava essere un modo terribilmente loquace per farlo .

Lo svantaggio principale è che lo sviluppatore deve ricordare di impostare IsUpdated in ciascun metodo nell'entità. Dimentica uno e non sarà in grado di rilevare le modifiche per quel valore. Ho accarezzato l'idea di una sorta di backing store personalizzato che potrebbe timestamp in modo trasparente le modifiche, che a sua volta potrebbe rendere IsUpdated una proprietà di sola lettura che il repository potrebbe utilizzare per aggregare gli aggiornamenti.

Il repository utilizza un'unità di implementazione del modello di lavoro che basa le sue azioni sul timestamp generato quando la radice aggregata è stata aggiunta ad essa. Dal momento che potrebbero esserci più entità queu

È stato utile?

Soluzione

In breve, la mia risposta è che sono andato con quello che ho proposto. Funziona, anche se sono sicuro che ci sia spazio per miglioramenti. I cambiamenti in realtà hanno richiesto pochissimo tempo, quindi penso che in questo caso non ho navigato troppo lontano dai principali KISS o YAGNI. : -)

Sento ancora che c'è spazio per i problemi relativi alle tempistiche delle operazioni, ma dovrei essere in grado di aggirarli nelle implementazioni del repository. Non è la soluzione ideale, ma non sono sicuro che valga la pena reinventare la ruota per correggere un problema che può essere evitato in meno tempo di quello necessario per risolvere.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top