Asked  7 Months ago    Answers:  5   Viewed   30 times

I'm trying to get my head around how to properly use the repository pattern. The central concept of an Aggregate Root keeps coming up. When searching both the web and Stack Overflow for help with what an aggregate root is, I keep finding discussions about them and dead links to pages that are supposed to contain base definitions.

In the context of the repository pattern, what is an aggregate root?

 Answers

61

In the context of the repository pattern, aggregate roots are the only objects your client code loads from the repository.

The repository encapsulates access to child objects - from a caller's perspective it automatically loads them, either at the same time the root is loaded or when they're actually needed (as with lazy loading).

For example, you might have an Order object which encapsulates operations on multiple LineItem objects. Your client code would never load the LineItem objects directly, just the Order that contains them, which would be the aggregate root for that part of your domain.

Tuesday, June 1, 2021
 
DaveRandom
answered 7 Months ago
32

Sure, a function to create and dispose your Connection will work great.

protected void Execute(Action<IDbConnection> query)
{
    using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDB"].ConnectionString))
    {
        query.Invoke(db);
    }
}

And your simplified call site:

public void SaveCustomer(CustomerDTO custDTO)
{
    Execute(db => db.Execute(saveCustSp, custDTO, CommandType.StoredProcedure));
}

With Return Values:

public T Get<T>(Func<IDbConnection, T> query)
{
    using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["myDB"].ConnectionString))
    {
        return query.Invoke(db); 
    }
}

In your call site, just write the logic you wish to use.

public IEnumerable<EmployeeDTO> GetEmployeeDetails(int employeeId)
{
    return Get<IEnumerable<EmployeeDTO>(db => 
        db.Query<EmployeeDTO>(anotherSp, new { EmployeeID = employeeId }, CommandType.StoredProcedure));
}
Wednesday, June 9, 2021
 
nfechner
answered 6 Months ago
96

Perhaps the AggregateRoot1 repository could call AggregateRoot2 repository when it's constructing the the AggregateRoot1 entity.

I don't think this invalidates ddd since the repositories are still in charge of getting/creating their own entities.

Monday, June 21, 2021
 
Domiik
answered 6 Months ago
58

I think that you only want to display summarized information. These bits of summarized information are no entities or value objects of the domain model. They are only information, nothing more.

It is something like showing reporting information. If I deal with such things, I would not stick to the pure DDD approach. Your suggested options are OK, because it's getting your job done. DDD should be not treated as dogma. Think outside the box. Loosen up a bit DDD.

But be aware that you are just creating informational values outside the model for displaying purpose. So if a user selects one bit of information to make some operation with it (which is defined in the domain model), you need to extract the identifier from the informational values and pull out the entity/value object/aggregate from a repository.

I strongly recommend this video: Eric Evans: What I've learned about DDD since the book. If you read his book, you really should see the whole video. Pay very close attention at about time 30:00 where Eric Evans himself talks about aggregates and refers to the problem you currently have.

Saturday, July 31, 2021
 
user3599828
answered 4 Months ago
67

In my opinion there is nothing wrong with this approach:

Order order = orderRepository.find(orderId);
order.updateQuantity(orderLineId, 2);

orderLineId is a 'local identity'. It is specific to aggregate root and does not make sense outside of it. You don't have to call it an 'id', it can be 'order line number'. From Eric Evan's book:

ENTITIES inside the boundary have local identity, unique only within the AGGREGATE.

...only AGGREGATE roots can be obtained directly with database queries. All other objects must be found by traversal of associations.

Tuesday, September 28, 2021
 
GSree
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share