2011-09-28 12 views
5

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?

risposta

4

ho letto il "libro blu" di DDD (Evans), così come Nilsson e non sono chiaro quale approccio alla validazione dovrei prendere.

Il libro blu affronta il problema da un'angolazione diversa. Penso che il termine "Validazione" non venga usato perché è pericoloso overgeneralization. Un approccio migliore è pensare all'invarianza dell'oggetto , non alla convalida. Gli oggetti (non solo in DDD) dovrebbero far rispettare i loro invarianti interni stessi. Non è UI o servizi o contratti o mapper o 'framework di validazione' o qualsiasi altra cosa esterna agli oggetti. Gli invarianti sono applicati internamente.È possibile trovare queste risposte utili: 1, 2, 3, 4.

potrei anche mettere guardie nelle setter di proprietà che impediscono valori inaccettabili per sempre di mettere il soggetto in un invalido Stato. Ciò significherebbe che AutoMapper fallirebbe nel tentativo di mappare un valore non valido.

Probabilmente non ci si deve preoccupare che AutoMapper non funzioni o non usi affatto AutoMapper. Gli oggetti di dominio dovrebbero incapsulare e forzare i loro invarianti interni e generare un'eccezione se il tentativo di romperlo è fatto. È molto semplice e non dovresti compromettere la semplicità e l'espressività dei tuoi oggetti di dominio a causa di alcuni problemi infrastrutturali. L'obiettivo di DDD non è quello di soddisfare i requisiti di AutoMapper o di qualsiasi altro framework. Se il framework non funziona con i tuoi oggetti di dominio non usarlo.

+0

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

+1

È 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

+0

@SonOfPirate - Proprio come una questione di interesse, uso CodeContracts per forzare invarianti nei miei oggetti di dominio. – RobertMS

1

Ci sono due tipi di convalida: coerenza

  1. Oggetto: E 'la responsabilità degli enti. Le entità non dovrebbero consentire di impostarle su uno stato non valido, le dipendenze dovrebbero essere applicate, i valori dovrebbero essere nell'intervallo. devi progettare metodi e proprietà e costruttori di classi per non consentire uno stato non valido.

  2. Validazione dei ruoli aziendali: questo tipo di convalida richiede l'elaborazione del server, come la verifica della disponibilità dell'ID, dell'unicità dell'email e così via. questi tipi di convalida devono essere elaborati nel server come Validatori o Specifiche prima della persistenza.

+3

Offro che c'è un terzo: convalida dell'interfaccia utente. Questo ha lo scopo di fornire un feedback interattivo all'utente. Penso che questo sia il luogo in cui più dei framework di validazione (come Annotazioni di dati e Libreria di impresa) sono mirati piuttosto che implementare gli altri due tipi. – SonOfPirate

+1

Sì, hai ragione, mi sono concentrato sulla convalida del livello dominio, c'è anche una convalida nell'interfaccia utente che verrebbe gestita nei modelli di visualizzazione o nel modello di presentazione utilizzando qualsiasi framework di convalida UI compatibile –

+0

concordo con te deve avere un'autovalutazione dominio. immetti alcuni validatori negli oggetti del dominio per convalide complesse (regole aziendali)? e disponi di convalide di base nel livello applicazione per i comandi (DTO)? – danfromisrael