Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repository vs Domain Services

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.

like image 951
Jeff Avatar asked Dec 20 '10 06:12

Jeff


1 Answers

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.

like image 109
Roger Johansson Avatar answered Oct 02 '22 12:10

Roger Johansson