Queries and Commands
Come detto in precedenza, il layer di presentazione comunica con la business logic attraverso query e comandi. Entrambi sono normali oggetti C# istanziati dal metodo dell'endpoint, ed inviati ad un IMediator, che a sua volta attiva l'handler corrispondente all'oggetto inviato (es. GetSiteQuery -> GetSiteQueryHandler).
Nonostante comandi e query a livello di codice siano la stessa cosa, la distinzione dei nomi sottolinea la differenza nell'use: le query sono usate per operazioni di sola lettura, mentre i comandi alterano lo stato dell'applicazione (aggiunta di una pagina, aggiornamento delle credenziali del server mail, ecc.).
Oggetti Query e Comando
Query e comandi sono classi C# che derivano da MediatR.Request e contengono le informazioni necessarie al layer applicativo per poter eseguire la richiesta. Per esempio:
public class GetPageQuery : MediatR.Request {
public Guid SiteId { get; set; }
public Guid PageId { get; set; }
}
...
public class SetMailServerCommand : MediatR.Request {
public Guid SiteId { get; set; }
public string Username { get; set; }
public string? Password { get; set; }
public string Host { get; set; }
public int Port { get; set; }
}
Handler
Per ogni tipo di query o comando, è definito un handler:
public class GetPageQueryHandler : MediatR.RequestHandler<GetPageQuery, PageResponse> {
public Task<PageResponse> Handle(GetPageRequest request) {
//Run db calls, mappings, etc..
}
}
Inviare Query e Comandi
Per inviare una richiesta è necessario un riferimento ad un'istanza di IMediator. Una volta configurato per utilizzare gli handler corretti (Persistence/ServiceConfiguration.cs), il mediator potrà essere iniettato in una classe controller API.
[Route("sites/{siteId}/pages")]
public class PagesController : Controller {
private readonly IMediator _mediator;
public PagesController(IMediator mediator){
_mediator = mediator;
}
...
[HttpGet]
public Task<PageResponse> GetPage(Guid siteId, Guid pageId){
var command = new GetPageQuery(siteId, pageId);
Task<PageResponse> response = _mediator.CreateStream(command);
return response;
}
}