混合不同数据源的存储库实现

时间:2013-09-04 09:47:33

标签: c# nhibernate repository

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服务。存储库的重点在于应用程序不应该关心你要使用的是什么数据源,但是如果没有应用程序在某种程度上知道,我不会看到如何解释这些情况“我是这样的转到数据源x所以我们最好区别对待它。“

是否存在解决此问题的模式或实现?在我看来,如果您在整个应用程序中使用Database x和ORM y,那么存储库工作非常出色,但如果由于技术债务而导致存储库偏离,那么存储库的好处就会大大减少。

1 个答案:

答案 0 :(得分:0)

在您的UnitOfWork中,如建议的那样,您应该使用 TransactionScope 事务。 在您的情况下,它会升级到MSDTC并确保在提交或以其他方式回滚之前正确执行所有登记的操作。