¿Ventajas de crear un repositorio genérico frente a un repositorio específico para cada objeto?

Estamos desarrollando una aplicación MVC de ASP.NET y ahora estamos construyendo las clases de servicio / repositorio. Me pregunto si existen ventajas importantes en la creación de una interfaz genérica de IRepository que implementen todos los repositorios, en comparación con cada repositorio que tiene su propia interfaz única y un conjunto de métodos.

Por ejemplo: una interfaz genérica de IRepository podría verse (tomada deesta respuesta):

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();
}

Cada repositorio implementaría esta interfaz, por ejemplo:

CustomerRepository: IRepositoryProductRepository: IRepositoryetc.

La alternativa que hemos seguido en proyectos anteriores sería:

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);
}

En el segundo caso, las expresiones (LINQ o de otro tipo) estarían completamente contenidas en la implementación del Repositorio, quienquiera que esté implementando el servicio solo necesita saber a qué función del repositorio llamar.

Supongo que no veo la ventaja de escribir toda la sintaxis de expresión en la clase de servicio y pasar al repositorio. ¿No significaría esto que el código LINQ fácil de desordenar se está duplicando en muchos casos?

Por ejemplo, en nuestro antiguo sistema de facturación, llamamos

InvoiceRepository.GetSingleInvoice(DateTime invoiceDate, int accountId)

desde unos pocos servicios diferentes (Cliente, Factura, Cuenta, etc.). Eso parece mucho más limpio que escribir lo siguiente en varios lugares:

rep.GetSingle(x => x.AccountId = someId && x.InvoiceDate = someDate.Date);

La única desventaja que veo al usar el enfoque específico es que podemos terminar con muchas permutaciones de las funciones Get *, pero esto todavía parece preferible a empujar la lógica de expresión hacia arriba en las clases de Servicio.

¿Qué me estoy perdiendo?

Respuestas a la pregunta(5)

Su respuesta a la pregunta