Chúng tôi đang phát triển một ứng dụng ASP.NET MVC và hiện đang xây dựng các lớp lưu trữ/dịch vụ. Tôi tự hỏi nếu có bất kỳ lợi thế lớn nào để tạo ra một giao diện IRepository chung mà tất cả các kho lưu trữ đều được thực hiện, so với mỗi Repository có giao diện và tập hợp các phương thức duy nhất của riêng nó.Lợi thế của việc tạo kho lưu trữ chung so với kho lưu trữ cụ thể cho từng đối tượng?
Ví dụ: một giao diện IRepository generic có thể trông giống như (lấy từ this answer):
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();
}
Mỗi Repository sẽ thực hiện giao diện này, ví dụ:
- CustomerRepository: IRepository
- ProductRepository : IRepository
- vv
Các thay thế mà chúng tôi đã theo dõi các dự án trước sẽ là:
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);
}
Trong trường hợp thứ hai, các từ ngữ (LINQ hay cách khác) sẽ được hoàn toàn chứa trong việc thực hiện Repository, bất cứ ai đang triển khai các dịch vụ chỉ cần biết chức năng kho lưu trữ nào cần gọi.
Tôi đoán tôi không thấy lợi thế của việc viết tất cả cú pháp biểu thức trong lớp dịch vụ và chuyển đến kho lưu trữ. Điều này có nghĩa là mã LINQ dễ bị lộn xộn đang được sao chép trong nhiều trường hợp?
Ví dụ, trong hệ thống hóa đơn cũ của chúng tôi, chúng ta gọi là
InvoiceRepository.GetSingleInvoice(DateTime invoiceDate, int accountId)
từ một vài dịch vụ khác nhau (khách hàng, hóa đơn, tài khoản, vv). Điều đó có vẻ sạch hơn nhiều so với văn bản sau đây ở nhiều nơi:
rep.GetSingle(x => x.AccountId = someId && x.InvoiceDate = someDate.Date);
Những bất lợi duy nhất tôi thấy việc sử dụng các phương pháp cụ thể là chúng ta có thể kết thúc với nhiều hoán vị của lệnh Get * chức năng, nhưng điều này vẫn có vẻ thích hợp hơn để đẩy biểu thức logic vào các lớp Service.
Tôi đang thiếu gì?
Nghiêm túc, câu trả lời tuyệt vời. Cảm ơn! –
Vì vậy, làm thế nào bạn sẽ sử dụng IoC/DI với điều này? (Tôi là một người mới ở IoC) Câu hỏi của tôi liên quan đến mẫu của bạn đầy đủ: http://stackoverflow.com/questions/4312388/how-should-i-use-ioc-di-with-this-repository-pattern – dan
"một kho lưu trữ là một phần của miền được mô hình hoá và tên miền đó không phải là chung chung. Không phải mọi thực thể đều có thể bị xóa, không phải mọi thực thể đều có thể được thêm vào, không phải mọi thực thể đều có một kho" hoàn hảo! – adamwtiko