Zaleta tworzenia ogólnego repozytorium w porównaniu z konkretnym repozytorium dla każdego obiektu?

Opracowujemy aplikację ASP.NET MVC i teraz budujemy klasy repozytorium / usługi. Zastanawiam się, czy istnieją jakieś główne zalety tworzenia ogólnego interfejsu IRepository, który implementują wszystkie repozytoria, a każde repozytorium ma swój własny, unikalny interfejs i zestaw metod.

Na przykład: ogólny interfejs IRepository może wyglądać (wzięty zta odpowiedź):

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

Każde repozytorium implementowałoby ten interfejs, na przykład:

CustomerRepository: IRepositoryProductRepository: IRepositoryitp.

Alternatywą, którą obserwowaliśmy w poprzednich projektach, byłaby:

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

W drugim przypadku wyrażenia (LINQ lub inne) będą całkowicie zawarte w implementacji repozytorium, ktokolwiek implementuje usługę, musi tylko wiedzieć, która funkcja repozytorium ma zostać wywołana.

Myślę, że nie widzę przewagi zapisywania całej składni wyrażenia w klasie usług i przechodzenia do repozytorium. Czy nie oznacza to, że w wielu przypadkach powielany jest łatwy w obsłudze kod LINQ?

Na przykład w naszym starym systemie fakturowania dzwonimy

InvoiceRepository.GetSingleInvoice(DateTime invoiceDate, int accountId)

z kilku różnych usług (klient, faktura, konto itp.). Wydaje się to znacznie czystsze niż pisanie poniższego w wielu miejscach:

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

Jedyną wadą, którą widzę, aby użyć specyficznego podejścia, jest to, że możemy skończyć z wieloma permutacjami funkcji Get *, ale wydaje się, że jest to lepsze niż wypychanie logiki wyrażeń do klas Service.

czego mi brakuje?

questionAnswers(5)

yourAnswerToTheQuestion