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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With