Nel livello di facciata del servizio, ho una classe di servizio con un metodo/operazione che accetta un oggetto DTO (contratto di dati). AutoMapper viene utilizzato per mappare questo DTO in un'istanza del mio oggetto dominio per applicare eventuali modifiche. La richiesta viene passata al mio servizio di dominio che esegue il lavoro effettivo. Ecco ciò che il metodo potrebbe essere simile:Convalida con DDD nell'applicazione SOA utilizzando IoC
public EntityContract AddEntity(EntityContract requestContract)
{
var entity = Mapper.Map<EntityContract, Entity>(requestContract);
var updatedEntity = Service.AddEntity(entity);
var responseContract = Mapper.Map<Entity, EntityContract>(updatedEntity);
return responseContract;
}
il servizio e Mapper proprietà sono impostate utilizzando l'iniezione del costruttore con Unity come il contenitore IoC.
Nell'eseguire l'operazione, il servizio di dominio apporta modifiche all'entità quindi utilizza un repository a persistere i cambiamenti come:
public Entity AddEntity(Entity entity)
{
// Make changes to entity
Repository.Add(entity);
// Prepare return value
}
Repository è impostato usando iniezione del costruttore.
Il problema è che i dati diventano immediatamente disponibili per altri client una volta che è stato mantenuto, quindi devo assicurarmi che non vengano mantenuti dati non validi. Ho letto il "libro blu" di DDD (Evans) e Nilsson e non sono chiaro quale approccio adottare per la convalida.
Se il mio obiettivo è impedire all'entità di entrare in uno stato non valido, dovrei convalidare entityContract nel mio metodo di servizio per garantire che tutte le regole siano soddisfatte prima di passare la richiesta al mio servizio di dominio? Esito a farlo perché sembra che sto rompendo l'incapsulamento con queste regole definite nella facciata del servizio.
La ragione per cui stiamo usando un sottile strato di facciata delegante ai servizi di dominio è che stiamo esponendo interfacce a grana fine nella nostra API ma il riutilizzo del supporto tramite la composizione dei servizi di dominio a grana fine. Tenendo presente che servizi di facciata multipli possono chiamare lo stesso metodo di servizio di dominio, forse la delega di queste regole nel servizio di dominio sarebbe meglio, quindi sappiamo che ogni uso è convalidato. O dovrei convalidare in entrambi i posti?
Potrei anche mettere delle guardie nei setter che impediscono che valori inaccettabili mettano l'entità in uno stato non valido. Ciò significherebbe che AutoMapper fallirebbe nel tentativo di mappare un valore non valido. Tuttavia, non aiuta quando nessun valore è mappato.
Non riesco ancora a superare il pensiero che queste regole siano parte del comportamento dell'entità e determinare se l'oggetto sia valido dovrebbe essere incapsulato all'interno dell'entità. È sbagliato?
Quindi prima devo determinare quando e dove eseguire questi controlli di convalida. Quindi ho bisogno di capire come implementare con DI in modo che le dipendenze siano disaccoppiate.
Quali suggerimenti puoi fornire?
I collegamenti sono fantastici. Ora mi è chiaro che il tipo interattivo di convalida che consente all'oggetto di entrare in uno stato non valido e fornisce un elenco di errori (tramite IDataErrorInfo, ad esempio) appartiene al livello UI/Presentazione (ViewModel). E sto bene mettendo le guardie nei miei oggetti di dominio per impedire che entrino in uno stato non valido. Ma stai difendendo anche mettendo i controlli nel livello di servizio e/o facciata a meno che non si estendano su più entità/aggregati? – SonOfPirate
È possibile aggiungere ulteriori controlli ai servizi e all'interfaccia utente secondo necessità. Il mio punto è che gli oggetti di dominio non dovrebbero fare affidamento su questi controlli. – Dmitry
@SonOfPirate - Proprio come una questione di interesse, uso CodeContracts per forzare invarianti nei miei oggetti di dominio. – RobertMS