OdeToCode IC Logo

Repositories and the Save Method

Sunday, June 13, 2010

One of the questions I've been getting lately goes like this:

Should a Repository class have a Save method?

And the standard answer:

It depends.

It's hard to keep track of all the different approaches to implementing the repository pattern these days, but I assume when someone asks me this type of question they are thinking of using code like this:

var employee = new Employee();
employeeRepository.Save(employee);

var account = new Account();
accountRepository.Save(account);

This style always strikes me as odd. It looks like code that wants to move away from an active record approach, but the code hasn't quite reached escape velocity. That's not to say the approach doesn't work. I can think of a couple scenarios where this approach can work well:

  • Applications using a single screen to edit each entity type (straight up CRUD).
  • Applications using the concept of aggregate roots from domain-driven design.

In other scenarios I think this approach only creates additional complications in sharing connections, transaction management, and maintaining entity identities. That's why I expect most repositories to work in conjunction with a unit of work object.

var employee = new Employee();
employeeRepository.Add(employee);

var account = new Account();
accountRepository.Add(account);

uow.Commit();

It's a small difference in code, but a considerable difference in philosophy. No entities are persisted until the unit of work commits. Behind the scenes, each repository working inside the same logical transaction is associated with the same unit of work. This approach simplifies the issues revolving around connections, transactions, and identity.