Gestione dell'implementazione generica e specifica

1

Normalmente abbiamo un codice che è comune per molte classi derivate (se non tutte). Un esempio potrebbe essere un repository generico (dove potrei avere un generico Aggiungi, Rimuovi, Conteggio, Max, Carica ecc. O un modello generico (ad esempio, una regola aziendale comune per ottenere un valore univoco per una nuova entità in base al tipo di proprietà, o un metodo di salvataggio generico, ecc.)

Ora, se dovessi creare un modello generico che accetti un repository generico, potrebbe apparire ilke:

GenericModel<TEntity> : IGenericModel<TEntity>
{
    internal GenericModel(IRepository<TEntity> genericRepository)
    {

    }
    protected IRepository<TEntity> Repository {get; }
}

Ora ho bisogno di un modello specifico con un repository specifico:

class ActivityModel : GenericModel<Activity>
{
    protected ActivityModel(IActivityRepository activityRepository)
}

dove

class ActivityRepository : GenericRepository<Activity>, IActivityRepository { }

Ciò significa che in ActivityModel ho bisogno di trasmettere la proprietà del repository a IActivityRepository ogni volta che devo usare i metodi specifici di IActivityRepository o posso dichiarare una nuova proprietà in ActivityModel

private new IActivityRepository Repository {get { return base.Repository; } }

per nascondere la proprietà base.Repository, ma non sono sicuro se sto facendo qualcosa di sbagliato usando questo approccio.

Un altro approccio sarebbe aggiungere un altro parametro generico

class GenericModel<TEntity, TRepository> where TRepository : IRepository<TEntity>

ma non sono sicuro che sia anche un approccio corretto.

Quindi qualche idea su come gestire implementazioni generiche e specifiche?

    
posta Goran 16.07.2018 - 12:15
fonte

1 risposta

2

È un aspetto generale dell'ereditarietà che non puoi rimuovere materiale.

Nel tuo esempio specifico potresti semplicemente ignorare il repository protetto, ma potenzialmente interromperà ulteriormente l'ereditarietà, o almeno lo confonderai.

Una semplice soluzione non dovrebbe assolutamente essere ereditata da GenericModel, ma suppongo che possiamo assumere che GenericModel abbia alcune altre funzionalità pubbliche che fai vuoi usare.

La risposta generale è: "Preferisci la composizione sull'ereditarietà", evita completamente il GenericModel e disponi di un IRepository privato dove richiesto. Quindi puoi semplicemente passare a un repository specifico nelle classi che lo utilizzano.

es:

public class ActivityModel : IGenericFunctionality
{
    public ActivityModel(
        IActivityRepository activityRepository,
        IGenericFunctionalityProvider gfp
    )
    {
        this.gfp = gfp;
        this.activityRepository = activityRepository;
    }

    public void GenericFunctionality() 
    {
        this.gfp.GenericFunctionality();
    }
}
    
risposta data 16.07.2018 - 16:23
fonte

Leggi altre domande sui tag