Sto guardando usando hexagonal / ports & gli adattatori disegnano in qualche codice su cui sto lavorando e per la maggior parte sono contento, ma c'è una parte che non riesco a capire come gestire la necessità di valori di ritorno diversi da una singola chiamata.
Userò un esempio per illustrare meglio, questo è pseudo codice, quindi i nomi non sono rappresentativi del codice reale.
Se ho un "servizio" di dominio che ha un metodo AddEntity posso avere 3 resi:
- Oggetto appena aggiunto
- Dati non validi
- L'entità esiste già
L'adattatore che utilizza questo "servizio" prenderà quindi il ritorno e invierà i dati nell'oggetto (potrebbe trasformarlo prima in un "modello di visualizzazione").
In C # l'adattatore potrebbe essere un controller WebApi con codice simile a questo:
public IHttpActionResult Post(DataViewModel entityData)
{
var item = this.service.AddEntity(entityData.Name, entityData.Description);
if (item == null)
{
return this.StatusCode(HttpStatusCode.Conflict);
}
var viewModel = Mapper.Map<EntityDTO, DataViewModel>(item);
return this.Created(this.Url.Link("DefaultApi", new { controller = "Entity", id = viewModel.Id }), viewModel);
}
Il problema, come puoi vedere, è che al momento può gestire solo 2 ritorni, o ottiene l'entità DTO che mappa e ritorna al client o diventa nullo e restituisce semplicemente un codice HttpStatus di conflitto.
Quello che sto cercando di capire è come potrei tornare all'adattatore, controller nell'esempio sopra, sia l'oggetto o uno dei due messaggi.
Gli approcci che ho considerato sono:
- estendere la classe entityDTO per avere informazioni aggiuntive che mi permettano di passare qualcosa che indica un problema (forse un enum?)
- innalzamento delle eccezioni digitate e gestione delle eccezioni
- raccolta di eventi
se usassi l'enum, il codice del controller sarebbe simile a questo:
public IHttpActionResult Post(DataViewModel entityData)
{
var item = this.service.AddEntity(entityData.Name, entityData.Description);
if(item.result == Result.Conflict)
{
return this.StatusCode(HttpStatusCode.Conflict);
}
if (item.result == Result.Invalid)
{
return this.StatusCode(HttpStatusCode.Invalid);
}
var viewModel = Mapper.Map<EntityDTO, DataViewModel>(item);
return this.Created(this.Url.Link("DefaultApi", new { controller = "Entity", id = viewModel.Id }), viewModel);
}
Di queste estensioni del DTO sembra l'opzione meno valida, ma non sono sicuro se mi sia sfuggito qualcosa nel modello che fornisce un modo semplice per farlo.
C'è qualche modo specifico per farlo che ho perso? o è una delle opzioni per l'ordinamento di questo ho menzionato sopra un modo migliore rispetto agli altri?