Mi sto trovando in grado di risolvere un problema di progettazione.
Per semplicità, userò C # (Web API).
Diciamo che ho una classe astratta RestController
:
public abstract class RestController
{
// ... Irrelevant code here
protected virtual async Task<IHttpActionResult> UseAuthorization(HttpMethod method, Func<Task<IHttpActionResult>> operation)
{
return await operation();
}
protected virtual async Task<IHttpActionResult> UseHttpCache(Func<Task<IHttpActionResult>> operation)
{
return await operation();
}
// ... Irrelevant code here
}
Questi due metodi sarebbero stati sovrascritti e reimplementati da classi figlio. Qualsiasi classe che vorrebbe solo estendere da RestController
e non vuole utilizzare le funzionalità di autorizzazione o cache, potrebbe semplicemente voler lasciare intatti questi metodi, poiché l'implementazione di base predefinita non fa nulla.
Ora, stavo pensando di avere qualcosa del genere:
public abstract class CachedRestController : RestController
{
protected override async Task<IHttpActionResult> UseHttpCache(Func<Task<IHttpActionResult>> operation)
{
IHttpActionResult result = await operation();
return new HttpCachedResult(result);
}
}
public abstract class AuthenticatedRestController : RestController
{
protected override async Task<IHttpActionResult> UseAuthorization(HttpMethod method, Func<Task<IHttpActionResult>> operation)
{
return IsAuthenticated(method) ?
await operation() :
Unauthorized();
}
}
Il mio obiettivo è raggiungere qualcosa di simile al seguente:
public class MyController : CachedRestController, AuthenticatedRestController
{
}
Aggiungere o rimuovere funzionalità (memorizzazione nella cache, autenticazione, ecc.), sarebbe facile come aggiungere o rimuovere le classi genitore.
Purtroppo, come tutti sappiamo, l'ereditarietà multipla non è supportata in C #, quindi non posso andare con quella soluzione.
Sto cercando un buon modello di progettazione (compatibile con C #) che otterrebbe più o meno ciò che sto cercando.
Conosco il Design pattern di Decorator , ma avere un controller come un campo mi fa quasi paura, dato che sono responsabile della sua creazione (il framework Web Api dovrebbe esserne responsabile).