存储库与域服务

发布于 2024-10-08 18:01:54 字数 950 浏览 2 评论 0原文

我对 DDD 和存储库的探索越多,我就越觉得自己被领域服务方法所吸引。

我内心深处不喜欢存储库(至少在我读过的示例和文章中)不是单语句原子这一事实。

  using (var customerRepository = GetCustomerRepository()) 
  {
      customerRepository.AddCustomerForDelete(someCustomer);
      customerRepository.SaveChanges();
  }

有很多我不喜欢的事情。一般来说,存储库本身成为一个问题并且必须维护(它是 IDisposable 并且需要“提交”)。看来我并没有对持久性问题进行太多抽象。

一个更简单、更符合我内心的方法是:

  GetCustomerService().DeleteCustomer(someCustomer);

它是原子的。没有存储库实例可供维护、处置或保存更改。如果您确实需要聚合根上的单个操作之外的工作单元支持,请合并某种数据范围支持(类似于 TransactionScope):

 using(var ds = new DataScope())
 {
     // both of these happen under the same underlying DbConnection or whatever
     GetCustomerService().DeleteCustomer(someCustomer1);
     GetCustomerService().DoSomethingElse(someCustomer2);
 }

在上述两个例子中,假设它们位于某些业务控制器和用于数据访问的底层机制(位于存储库或服务实现内部)是实体框架 ObjectContext。客户是某种聚合根。

请告诉我存储库方法更好。

谢谢。

the more I explore DDD and repositories, the more I feel myself drawn to a domain services approach instead.

Something in my gut doesn't like the fact that a repository (at least in the examples and articles I've been reading) is not single statement atomic.

  using (var customerRepository = GetCustomerRepository()) 
  {
      customerRepository.AddCustomerForDelete(someCustomer);
      customerRepository.SaveChanges();
  }

There's a bunch of things I just don't like about this. In general, the repository itself becomes a concern and must be maintained (it's IDisposable and requires a "Commit"). It doesn't seem like I'm abstracting persistence concerns all that much.

A much simpler approach that seems to sit better in my gut is:

  GetCustomerService().DeleteCustomer(someCustomer);

It's atomic. There's no instance of a repository to maintain, dispose, or save changes on. And if you REALLY REALLY need unit of work support outside of a single operation on an aggregate root, incorporate some kind of data scope support (akin to a TransactionScope):

 using(var ds = new DataScope())
 {
     // both of these happen under the same underlying DbConnection or whatever
     GetCustomerService().DeleteCustomer(someCustomer1);
     GetCustomerService().DoSomethingElse(someCustomer2);
 }

In both of the above, for example's sake, lets say they are in some business controller and the underlying mechanism (sitting inside the repository or service implementation) for data access is an Entity Framework ObjectContext. And a Customer is some aggregate root.

Please show me that a repository approach is better.

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

真心难拥有 2024-10-15 18:01:54

我想说的是,您只见过存储库模式的幼稚示例。
没有任何内容表明存储库应该具有原子方法。

我的方法与您的数据范围方法几乎相同:(

using(var uow = UoW.Begin())
{
    var customerRepo = new CustomerRepository(uow);
    customerRepo.Remove(someCustomer);
    uow.Commit();
}

我的方法基于 Jimmy Nilssons 在《应用领域驱动设计和模式》一书中的 NWorkspace 想法)

这样,我可以将不同类型的 UoW 传递到我的存储库。
例如,基于 EF4 的 uow 或基于对象的 linq uow,并且仍然在存储库内使用相同的 linq 查询。

I'd say that you've only seen naive examples of repository pattern.
There is nothing that says that a repository should have atomic methods.

My approach is pretty much identical to your datascope approach:

using(var uow = UoW.Begin())
{
    var customerRepo = new CustomerRepository(uow);
    customerRepo.Remove(someCustomer);
    uow.Commit();
}

(My approach is based on Jimmy Nilssons NWorkspace ideas in his book Applying Domain Driven Design and patterns)

This way, I can pass different types of UoW's to my repositories.
e.g. a EF4 based uow or an linq to objects based uow and still use the same linq queries inside the repositories.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文