Question

Je cherche à voir quelles approches les gens auraient pu prendre pour détecter les changements dans les entités faisant partie de leurs agrégats. J'ai quelque chose qui fonctionne, mais je n'en suis pas folle. Fondamentalement, mon référentiel est chargé de déterminer si l'état d'une racine agrégée a changé. Supposons que j'ai une racine d'agrégat appelée Book et une entité appelée Page dans l'agrégat. Un Livre contient une ou plusieurs entités Page , stockées dans une collection Pages .

En règle générale, les scénarios d'insertion et de mise à jour sont effectués en inspectant la racine agrégée et ses entités pour déterminer la présence d'une clé. Si la clé est présente, il est présumé que l'objet a été, à un moment donné, sauvegardé dans la source de données sous-jacente. Cela en fait un candidat pour une mise à jour; mais ce n'est pas définitif basé sur cela seul pour les entités. Avec la racine agrégée, la réponse est évidente, puisqu'il n'y en a qu'un et que c'est le point d'entrée singulier, on peut supposer que la présence d'une clé dictera l'opération. Dans mon cas, il est acceptable de sauvegarder la racine agrégée elle-même afin que je puisse capturer une date de modification.

Pour faciliter ce comportement des entités elles-mêmes, ma classe EntityBase contient deux propriétés simples: IsUpdated () , IsDeleted () . Ces deux valeurs par défaut sont false. Je n'ai pas besoin de savoir si c'est nouveau ou non, car je peux prendre cette décision en fonction de la présence de la clé, comme mentionné précédemment. Les méthodes de l'implémentation, dans ce cas la page, ont chacune des méthodes qui modifient le jeu de données de sauvegarde IsUpdated () en true.

Ainsi, par exemple, Page a une méthode appelée UpdateSectionName () qui modifie la valeur de sauvegarde de la propriété SectionName , qui est en lecture seule. Cette approche est utilisée de manière cohérente, car elle permet d’établir un point d’attachement logique des validateurs dans la méthode (empêchant l’entité de passer à un état non valide) qui effectue ce paramétrage de données. Le résultat final est que je dois mettre un this.IsUpdated () = true; à la fin de la méthode.

Lorsque la racine d'agrégat est envoyée dans le référentiel pour Save () (un commutateur logique vers un Insert () ou Update () operation), il peut ensuite parcourir la collection Pages du Livre , en recherchant les pages présentant l'un des trois scénarios suivants:

  1. Pas de clé. Un page sans clé sera inséré.
  2. IsDeleted = true; Une suppression remplace une mise à jour et la suppression sera validée - en ignorant toute mise à jour pour la Page .
  3. IsUpdated = true; Une mise à jour sera validée pour la page.

Cette façon de procéder m'empêche de mettre à jour aveuglément tout ce qui se trouve dans la collection Pages, ce qui pourrait être décourageant s'il y avait plusieurs centaines d'entités de Page dans le livre, par exemple. J'avais envisagé de récupérer une copie du livre, de faire une comparaison et de ne valider que les modifications détectées (insertions, mises à jour et suppressions en fonction de la présence et / ou de la comparaison), mais cela semblait être une façon terriblement bavarde de procéder. .

Le principal inconvénient est que le développeur doit se rappeler de définir IsUpdated dans chaque méthode de l'entité. Oubliez-en un et il ne pourra pas détecter les changements pour cette valeur. J'ai eu l'idée d'une sorte de magasin de sauvegarde personnalisé qui pourrait horodater les modifications de manière transparente, ce qui pourrait à son tour faire de IsUpdated une propriété en lecture seule que le référentiel pourrait utiliser pour agréger les mises à jour.

Le référentiel utilise une implémentation de modèle d'unité de travail qui fonde ses actions sur l'horodatage généré lors de l'ajout de la racine agrégée. Puisqu'il pourrait y avoir plusieurs entités en file d'attente

Était-ce utile?

La solution

En bref, ma réponse est que je suis allé avec ce que je proposais. Cela fonctionne, même si je suis sûr qu'il y a place à amélioration. Les changements ont en fait pris très peu de temps, alors j’ai l’impression de ne pas trop m'éloigner des principes de KISS ou de YAGNI dans ce cas. : -)

Je pense toujours qu'il est possible de régler les problèmes de synchronisation liés aux opérations, mais je devrais pouvoir les contourner dans les implémentations du référentiel. Ce n'est pas la solution idéale, mais je ne suis pas sûr qu'il soit utile de réinventer la roue pour corriger un problème qui peut être évité en moins de temps qu'il n'en faut pour réparer.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top