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 数据库,您将如何处理每个数据库会话的事务?
现在这肯定是一个人为的例子,但是我遇到的每个 Repository 实现似乎在某种程度上都知道它实际上是一个特定的数据库和正在使用的 ORM。
想象另一种情况,您有 2 个存储库,其中一个将访问数据库,另一个正在调用 Web 服务。Repositories 的全部意义在于,应用程序不应该关心您将使用什么数据源,但是如果不跳过一些巨大的障碍,我不知道如果应用程序不知道在某个级别上如何解释这些场景“仅供参考,这是转到数据源 x,所以我们最好区别对待”。
是否有解决此问题的模式或实现?在我看来,如果您在整个应用程序中使用 Database x 和 ORM y,那么 Repositories 工作得非常好,但如果由于技术债务而导致课程偏离,那么 Repositories 的好处就会大大降低。