ASP.NET MVCアプリケーションを開発しており、現在、リポジトリ/サービスクラスを構築しています。すべてのリポジトリが実装する汎用のIRepositoryインターフェイスを作成することには、各リポジトリが独自のインターフェイスとメソッドのセットを持っているのに対して、大きな利点があるのかと思います。
たとえば、汎用のIRepositoryインターフェイスは次のようになります(この回答から取得)。
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();
}
各リポジトリはこのインターフェースを実装します、例えば:
- CustomerRepository:IRepository
- ProductRepository:IRepository
- 等
以前のプロジェクトで従った代替案は次のとおりです。
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);
}
2番目のケースでは、式(LINQまたはその他)は完全にリポジトリ実装に含まれます。サービスを実装している人は、呼び出すリポジトリ関数を知る必要があるだけです。
サービスクラスにすべての式の構文を記述してリポジトリに渡すことの利点はわかりません。これは、多くの場合、使いやすいLINQコードが複製されていることを意味しませんか?
たとえば、以前の請求システムでは、
InvoiceRepository.GetSingleInvoice(DateTime invoiceDate, int accountId)
いくつかの異なるサービス(顧客、請求書、アカウントなど)から。複数の場所で次のように書くよりも、はるかにきれいに見えます。
rep.GetSingle(x => x.AccountId = someId && x.InvoiceDate = someDate.Date);
特定のアプローチを使用することで私が目にする唯一の欠点は、Get *関数の多くの順列が発生する可能性があることですが、これは式ロジックをServiceクラスにプッシュするよりも望ましいようです。
何が欠けていますか?