I am working on a project for a company that believes that suppliers perform services to redistribute employees. These services mean that the driving forces do not have experience, for example, for preparing the piano or for transit or creating boxes for valuables.
In this domain, the order has 1: many places.
In a moving industry, orders often go backwards until the supplier completes the services requested. Therefore, in our model, we have some statuses (for example, sent, canceled, in standby mode) that apply to orders and locations.
There are pretty simple business rules here. Here's a sample:
- When an order is placed on hold, all locations are placed on hold.
- A location cannot be withdrawn Hold, if its parent order is on hold.
Etc. From these rules, it seems obvious to me that this forms the cumulative border of the root. So I have a MyClient.Statuses.Order aggregate, where Statuses is the name of the context / service / of what you want to name:
public class Order { private Guid _id; private OrderStatus _status; public void PlaceOnHold() { if (_status == OrderStatus.Cancelled)
Both of these objects (Order, Location) have GUIDs in other contexts (for example, for CRUD-based attributes that have no states). So, now we finally come to my question:
How to write a command and a handler to place a place on hold?
I want to keep this DRY and Service-Oriented thing in order to minimize communication, but it is very difficult to maintain the relationship between parents and children between two objects in only one place.
Option 1 - Single Location ID:
public class PlaceLocationOnHold_V1 { public readonly Guid Id; } public class PlaceLocationOnHold_V1Handler { public void Handle(PlaceLocationOnHold_V1 command) {
Option 2 - Order ID and Location ID:
public class PlaceLocationOnHold_V2 { public readonly Guid OrderId;
Option 3 is the only parameter with a class that encapsulates "A Location owned by order"
public class LocationIdentity { public Guid Id; public Guid OrderId; } public class PlaceLocationOnHold_V3 { public readonly LocationIdentity Location; } public class PlaceLocationOnHold_V3Handler { public void Handle(PlaceLocationOnHold_V3 command) { var aggregate = _repository.GetById(command.Location.OrderId); aggregate.PlaceLocationOnHold(command.Location.Id); _repository.Save(); } }