Nous développons une application ASP.NET MVC et construisons maintenant les classes de référentiel / service. Je me demande s'il y a des avantages majeurs à créer une interface IRepository générique que tous les référentiels implémentent, par rapport à chaque référentiel ayant sa propre interface et un ensemble de méthodes uniques.
Par exemple: une interface générique IRepository pourrait ressembler à (tirée de cette réponse ):
public interface IRepository : IDisposable
{
T[] GetAll<T>();
T[] GetAll<T>(Expression<Func<T, bool>> filter);
T GetSingle<T>(Expression<Func<T, bool>> filter);
T GetSingle<T>(Expression<Func<T, bool>> filter, List<Expression<Func<T, object>>> subSelectors);
void Delete<T>(T entity);
void Add<T>(T entity);
int SaveChanges();
DbTransaction BeginTransaction();
}
Chaque référentiel implémenterait cette interface, par exemple:
- CustomerRepository: IRepository
- ProductRepository: IRepository
- etc.
L'alternative que nous avons suivie dans les projets précédents serait:
public interface IInvoiceRepository : IDisposable
{
EntityCollection<InvoiceEntity> GetAllInvoices(int accountId);
EntityCollection<InvoiceEntity> GetAllInvoices(DateTime theDate);
InvoiceEntity GetSingleInvoice(int id, bool doFetchRelated);
InvoiceEntity GetSingleInvoice(DateTime invoiceDate, int accountId); //unique
InvoiceEntity CreateInvoice();
InvoiceLineEntity CreateInvoiceLine();
void SaveChanges(InvoiceEntity); //handles inserts or updates
void DeleteInvoice(InvoiceEntity);
void DeleteInvoiceLine(InvoiceLineEntity);
}
Dans le second cas, les expressions (LINQ ou autre) seraient entièrement contenues dans l'implémentation du référentiel, quiconque implémente le service a juste besoin de savoir quelle fonction de référentiel appeler.
Je suppose que je ne vois pas l'avantage d'écrire toute la syntaxe d'expression dans la classe de service et de la transmettre au référentiel. Cela ne signifierait-il pas que du code LINQ facile à manipuler est dupliqué dans de nombreux cas?
Par exemple, dans notre ancien système de facturation, nous appelons
InvoiceRepository.GetSingleInvoice(DateTime invoiceDate, int accountId)
à partir de quelques services différents (client, facture, compte, etc.). Cela semble beaucoup plus propre que d'écrire ce qui suit à plusieurs endroits:
rep.GetSingle(x => x.AccountId = someId && x.InvoiceDate = someDate.Date);
Le seul inconvénient que je vois à l'utilisation de l'approche spécifique est que nous pourrions nous retrouver avec de nombreuses permutations de fonctions Get *, mais cela semble toujours préférable à pousser la logique de l'expression dans les classes Service.
Qu'est-ce que je rate?