1

Say I've got two simple entities: User and Review. How bad is it if User calls the Review repository? What is the "clean" way for the User to get its Reviews?

class User
{
    public function getReviews()
    {
        return reviewRepository.findByUser(this);
    }
}

I did have a look at this question, but although they say this is a bad practice, I didn't find an answer there.

Community
  • 1
  • 1
BenMorel
  • 34,448
  • 50
  • 182
  • 322

1 Answers1

3

The clean way in DDD is to have the UserRepository fill the reviews of the User when asking for a User.

class UserRepository
{
  public User GetUserByID(long userId)
  {
    var user = CreateUser();
    user.Reviews = FindReviewsforUser(userID);
    return user;
  }
}

But before you do this, you need to verify that your User Entity in your Domain is also an AggregateRoot! Only AggregateRoots have Repositories. Please take a look at this question to see or get some insights to the problems while desiging aggregateroots.

Community
  • 1
  • 1
rObiwahn
  • 238
  • 1
  • 5
  • here is another usefull link for aggregates: http://thinkddd.com/blog/2009/02/14/aggregates-and-aggregate-roots/ – rObiwahn Jul 25 '11 at 15:04
  • Yes, both User and Review are aggregate roots. I like your solution, however what bothers me is: because `FindReviewsforUser()` is only called once when the User is instantiated, what happens if we add a new Review for that User? `User.Reviews` will be outdated, whereas it would have been up to date if we'd called the Repository again. Am I missing something? – BenMorel Jul 26 '11 at 11:42
  • You never will get full synchronization. At least not in a n-tier architecture! if you would do it like user.AddReview(review); your user object would be in sync (in a local environment). – rObiwahn Jul 29 '11 at 12:08