Immaginiamo di avere un gruppo e utenti e quando l'utente vuole unirsi a un gruppo, sto chiamando il metodo groupsService.AddUserToGroup (gruppo, utente). In DDD dovrei fare group.JoinUser (utente), che sembra piuttosto buono.
DDD ti incoraggia inoltre a utilizzare i servizi (senza stato) per eseguire attività, se l'attività a portata di mano è troppo complessa o non si adatta a un modello di entità. Va bene avere servizi nel livello di dominio. Ma i servizi nel livello di dominio dovrebbero includere solo la logica aziendale. Le attività esterne e la logica dell'applicazione (come l'invio di un'e-mail) d'altra parte, dovrebbero utilizzare il servizio di dominio nel livello dell'applicazione, in cui è possibile disporre di un servizio separato (applicazione) che lo avvolge, ad esempio.
Il problema appare se ci sono alcune regole di convalida per l'aggiunta di un utente ...
Le regole di validazione appartengono al modello di dominio! Dovrebbero essere incapsulati all'interno degli oggetti del dominio (entità ecc.).
... o alcune attività esterne devono essere avviate quando l'utente viene aggiunto al gruppo. Avere questi compiti porterà all'entità con dipendenze esterne.
Anche se non so di che tipo di attività esterna stai parlando, suppongo sia qualcosa come inviare un'e-mail, ecc. Ma questo non fa davvero parte del tuo modello di dominio. Dovrebbe vivere nel livello dell'applicazione e essere impilato lì imho. È possibile disporre di un servizio nel livello applicazione che opera su servizi e entità di dominio per eseguire tali attività.
Ma il fatto che un'entità dipenda da alcuni servizi / classi esterni non mi sembra così buono e "naturale" per me.
È innaturale e non dovrebbe accadere. L'entità non dovrebbe conoscere cose che non sono di sua responsabilità. I servizi dovrebbero essere utilizzati per orchestrare le interazioni tra entità.
Qual è il modo corretto di gestirlo in DDD?
Nel tuo caso, la relazione dovrebbe probabilmente essere bidirezionale. Se l'utente si unisce al gruppo o il gruppo accetta l'utente dipende dal tuo dominio. L'utente si unisce al gruppo? Oppure l'utente viene aggiunto a un gruppo? Come funziona nel tuo dominio?
Ad ogni modo, hai una relazione bidirezionale e puoi quindi determinare la quantità di gruppi a cui l'utente appartiene già all'interno dell'aggregazione utente. Se si passa l'utente al gruppo o il gruppo all'utente è tecnicamente banale una volta determinata la classe responsabile.
La convalida dovrebbe quindi essere eseguita dall'entità. Il tutto viene chiamato da un servizio del livello applicazione che può anche fare cose tecniche, come l'invio di e-mail ecc.
Tuttavia, se la logica di convalida è davvero complessa, un servizio di dominio potrebbe essere una soluzione migliore. In tal caso, incapsulare le regole aziendali e quindi chiamarle dal livello applicazione.