In CQRS ma in generale in DDD è buona norma identificare il concetto di AggregateRoot con una classe specifica, e se fate EVENT SOURCING è una funzionalità praticamente obbligatoria, perchè l’AR si occupa anche di gestire il dispatch dei DOMAIN EVENTS sia agli eventy Applyer, sia anche al mondo esterno.
In questo caso molto spesso si tende a dotare la classe base astratta AggregateRoot di un Id che solitamente è di tipo GUID, oppure di tipizzarla con un generics su T in modo che T identifichi il tipo di dato usato per l’id. In questi gg sto “giocando” un po su questi concetti su un dominio “motore di blog” e come al solito, cambiando dominio, emergono alcune considerazioni che in altri casi non emergono.
In questo caso io ho il seguente scenario: ogni blog ha un nome ed ogni blog ragionevolmente avrà un AR che ne gestisce le categorie e questo AR sarà univoco per ogni blog. In questo caso se la mia AR ha un id di tipo GUID si potrebbe risolvere il tutto con un semplice listener che è in ascolto sull’evento BLOG CREATED, e crea un QueryModel che associa al nome del blog l’Id dell’AR che ne gestisce le categorie. Questo viene fatto perchè dalle MetaWeblogAPI tutte le chiamate non hanno guid, ma hanno il nome del blog, per cui se debbo aggiungere una categoria ad un blog parto dal nome del blog, leggo il queryModel che mi dice l’id dell’AR del category manager, carico l’AR dal suo id Guid e chiamo AddCategory().
Ma anche no!!!
La soluzione più semplice è quella di ammettere che l’AR del Category Manager abbia un Id stringa, e che, dato il nome del blog, l’id venga generato per convenzione (Es. CatManager_NomeBlog). In questo modo quando arriva un comando per aggiungere la categoria XXX al blog YYY io posso caricare l’AR CatManager_YYY e chiamare subito AddCategory(). A questo punto posso estendere il tutto dicendo che la classe AggregateRoot base ha un id di tipo stringa, in questo modo se voglio posso sempre usare un Id Guid convertendolo a stringa, ma posso risolvere situazioni più specifiche, come gli unique constraint in maniera decisamente semplice.
Anche in questo caso l’esperienza che se ne trae è: per ogni Dominio, le regole sono differenti e l’implementazione, che costituisce l’implementazione di tali regole, è differente. Motivo per il quale è praticamente impossibile se non improbabile pensare di creare librerie o architetture base per DDD, che sicuramente non potranno soddisfare esigenze specifiche del proprio dominio.
Happy DDD.
Gian Maria.