In poche parole, No, un aggregato non dovrebbe dipendere da un pezzo di stato per il quale non è la rappresentazione singola, autorevole e non ambigua. Il vero problema qui è che la domanda che stai ponendo è ortogonale al problema che stai cercando di risolvere.
Potresti riuscire a riorganizzare il tuo dominio attuale in un modo che potrebbe soddisfare i tuoi requisiti introducendo macchine a stati concorrenti in cui ogni stato ( ITGroupMember
, ecc.) è l'entità diretta responsabile dell'esecuzione delle tue azioni e ogni User
è dati una raccolta Membership
o simili, ma questo tipo di soluzione porterà indubbiamente a problemi lungo la strada ed è, francamente, molto più complesso del necessario.
In generale, l'autorizzazione / autenticazione sono preoccupazioni trasversali che non si prestano bene a essere modellate utilizzando i principi DDD. La semplice definizione dei requisiti per un tale sistema dovrebbe chiarire questo:
In termini astratti, per autorizzare qualsiasi comando dato nel tuo dominio, quel comando deve essere 1) iniettato con o 2) avvolto da un ulteriore pezzo di logica, ad esempio un AuthorizationContext
, in modo che i dati di Permissions
possano essere resi disponibili per quel comando per la convalida. In pratica, la soluzione più adatta è quella di avvolgere i comandi perché porta ad un accoppiamento inferiore (i comandi stessi non devono sapere nulla sull'autorizzazione).
Nei termini DDD, l'autorizzazione potrebbe assumere uno dei moduli sopra. Potresti iniettare ogni entità con il tuo AuthorizationContext
in modo che ogni metodo di entità abbia accesso ai dati necessari per l'autorizzazione (che riguarda ciò a cui sei atterrato e che chiedi qui), oppure potresti trattare ogni entità come una macchina di stato in cui ogni stato rappresenta un particolare insieme di permessi (in questo modo avvolge le chiamate al metodo). Nessuna di queste soluzioni è particolarmente elegante e entrambe introducono un accoppiamento extra e spostano l'attenzione del modello dall'esecuzione della logica di business. In quanto tale, non posso raccomandare uno dei due metodi precedenti.
L'approccio più tradizionale sarà semplicemente "aumentare" l'autorizzazione sopra il livello del dominio e autorizzare i comandi prima che vengano eseguiti. Questo può assumere la forma di thin service layer. Questo è di gran lunga il caso più comune. Quasi ogni framework web che ho incontrato esegue un'autorizzazione / autenticazione tramite una sorta di servizio middleware che viene richiamato prima dell'esecuzione di qualsiasi codice di dominio. La maggior parte usa una sorta di annotazione di dati direttamente sui metodi del controllore. Potresti semplicemente prendere una pagina da questo playbook e implementare qualcosa di simile (questo è essenzialmente solo un comando di mappatura della configurazione globale ai ruoli).
Se questo deve essere fatto secondo DDD, abbiamo bisogno di avere una discussione più ampia. Una pietra miliare del DDD è il refactoring verso intuizioni più profonde e l'esplicitazione implicita. Ricorda, l'obiettivo di DDD è quello di modellare i requisiti comportamentali di un sistema tale che il risultato sia un'astrazione utile del dominio aziendale. La chiave è concentrarsi sul comportamento di un sistema, non sui dati. Questo perché i dati di un determinato sistema raramente sono un buon punto di partenza per la modellazione dei requisiti funzionali. Il singolo problema più grande che vedo nel tuo dominio è l'inclusione di un'entità User
. Scommetterei il mio nipotino che l'unica ragione per cui esiste un'entità User
nel tuo dominio è perché hai una tabella [utente] / documento / qualsiasi cosa nel tuo archivio dati.
User
di solito è una scelta sbagliata per un oggetto di dominio perché denota quasi nessun comportamento e probabilmente include troppa conoscenza. Cosa fa il tuo Users
? Commento? %codice%. Vota? %codice%. Revisione? %codice%. Vedi dove vado? È necessario suddividere i dati verticalmente per raggruppare i dati correlati in base al comportamento . Forse un Commenter
ha un Rater
. Un Reviewer
ha bisogno di un Commenter
? No. I confini della normalizzazione sono molto improbabili che siano i confini di tutte le tue entità.
So cosa stai pensando. In che modo il partizionamento dell'entità PastCommentCollection
risolve il mio particolare problema riguardante l'autorizzazione? E a questo, lascerò tu con una domanda:
Che cosa succede se Rater
genera un PastCommentCollection
per ogni User
che non può essere correlato alle autorizzazioni appropriate necessarie per valutare qualcosa?