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?