Martin Fowler によって定義されたリポジトリは、メモリ内ドメイン オブジェクト コレクションのように機能することになっています。これにより、アプリケーションは (理論的には) 永続化メカニズムを認識しなくなります。
したがって、通常の状況では、次のようになります。
public void MyBusinessLogicMethod () {
...
IRepository<Customer> repository = myIocContainer.Resolve<IRepository<Customer>>();
repository.Add(customer);
}
ただし、実行したい一連の挿入/更新があり、それらのいずれかが失敗した場合にロールバックするメカニズムが必要な場合は、何らかの UnitOfWork 実装が必要になります。
public void MyBusinessLogicMethod () {
...
using (IUnitOfWork uow = new UnitOfWork()){
IRepository<Customer> customerRepo = myIocContainer.Resolve<IRepository<Customer>>(uow);
customerRepo.Add(customer);
IRepository<Order> orderRepo = myIocContainer.Resolve<IRepository<Order>>(uow);
orderRepo.Add(order);
IRepository<Invoice> invoiceRepo = myIocContainer.Resolve<IRepository<Invoice>>(uow);
invoiceRepo.Update(invoice);
uow.Save();
}
}
ただし、カスタマー リポジトリが SqlServer データベースに対して動作し、注文リポジトリが MySql データベースに対して動作し、請求書リポジトリが PostgreSQL データベースに対して動作するという奇妙な要件がある場合、各データベース セッションのトランザクションをどのように処理しますか?
これは確かに少し不自然な例ですが、私が遭遇したすべてのリポジトリ実装は、実際に特定のデータベースと ORM が使用されていることをある程度認識しているようです。
2 つのリポジトリがあり、1 つはデータベースにアクセスし、もう 1 つは Web サービスを呼び出しているという別のシナリオを想像してみてください。リポジトリの要点は、アプリケーションがどのデータ ソースにアクセスしようとしているのかを気にするべきではないということですが、いくつかの大規模なフープを飛び越えなければ、アプリケーションが何らかのレベルで認識していないと、これらのシナリオをどのように説明できるかわかりません。「参考までに、これはデータ ソース x に移動するため、別の方法で処理したほうがよいでしょう」.
この問題に対処するパターンまたは実装はありますか? アプリケーション全体にデータベース x と ORM y を使用している場合、リポジトリは素晴らしく機能するように思えますが、技術的負債が原因でコースが逸脱すると、リポジトリの利点が大幅に減少します。