207
CHAPTER 6 | Tackle Business Complexity in a Microservice with DDD and CQRS Patterns
Address = address;
// ...Additional code ...
}
public
void
AddOrderItem
(
int
productId,
string
productName,
decimal
unitPrice,
decimal
discount,
string
pictureUrl,
int
units =
1
)
{
//...
// Domain rules/logic for adding the OrderItem to the order
// ...
var
orderItem =
new
OrderItem
(productId, productName, unitPrice, discount,
pictureUrl, units);
_orderItems.
Add
(orderItem);
}
// ...
// Additional methods with domain rules/logic related to the Order aggregate
// ...
}
It is important to note that this is a domain entity implemented as a POCO class. It does not have any
direct dependency on Entity Framework Core or any other infrastructure framework. This
implementation is as it should be in DDD, just C# code implementing a domain model.
In
addition, the class is decorated with an interface named IAggregateRoot. That interface is an empty
interface,
sometimes called a
marker interface
, that is used just to indicate that this entity class is also
an aggregate root.
A marker interface is sometimes
considered as an anti-pattern; however, it is also a clean way to mark
a class, especially when that interface might be evolving. An attribute could be the other choice for
the marker, but it is quicker to see the base class (Entity) next to the IAggregate interface instead of
putting an Aggregate attribute marker above the class. It
is a matter of preferences, in any case.
Having an aggregate root means that most of the code related to consistency and business rules of
the aggregate’s entities should be implemented as methods in the Order aggregate root class (for
example, AddOrderItem when adding an OrderItem object to the aggregate). You should not create
or update OrderItems objects independently
or directly; the AggregateRoot class must keep control
and consistency of any update operation against its child entities.
Dostları ilə paylaş: