I see warehouses and locations as separate aggregates, at least when it comes to inventory management. Locations in the inventory management have invariants regarding as to what can be stored in them.
These are not just events of "placed pallet X in location Y" but we actively can prevent that somebody places a wrong pallet in a wrong location - for example if the location is currently undergoing stocktaking.
A warehouse can also have many locations - especially the larger, automated ones. This would mean that a single aggregate of warehouse + locations would be too big and potentially cause too many concurrency issues.
Currently, I'm trying to event source pretty much everything because I need events for many projections and to communicate across bounded contexts (with proper translation).
I must be able to source the location aggregate from its corresponding events. This is done by implementing a separate stream of events for each aggregate and my projections run off an aggregated stream of all events ($all in Event Store).This means that the event, which defines the location, must be on the Location aggregate - but I must be able to navigate from the warehouse to its locations, at least on a read model level.
A warehouse might have some invariants regarding the location (there are different warehouse types, which would probably best be modelled through generalisation or similar means). I'm not allowed to define a location for a delivery address of a different customer than the warehouse is associated with (in such warehouses that are associated with a single customer). These are however only really applicable for the master data management (or warehouse management), the inventory management would only use the existing definitions.
My current question is: how can I model the one-to-many relationship between the warehouse and location aggregates?
(oh god I hate the overzealous text editor of google groups. "Hey, let me make this italic, you like italic, don't you? Here, have it italic. Oh you didn't want it italic, I'm sure you just forgot how much you love italic text!")
Since the invariant might be on the warehouse, I need at least a method to define the relationship on the warehouse - which could fail.
var location = /* somehow define the location */
warehouse.AddLocation(location);
This event however does not define the location or at least in the current implementation of separating events per aggregate it wouldn't.
Therefore I need some way to define the location...
var location = new Location(id, name);
// or
var location = new Location(id, name, warehouseId);
var location = warehouse.AddLocation(id, name);
Is this a good idea?
However, now I've manipulated two aggregates in one action and I must know that I did this because I still have to persist and propagate the events that this created.
...with the "events are associated with an aggregate" implementation, this means that I now have to expect a Location Defined event on the location and a Location Added event for the warehouse. The order is also important here.
Technically, this could be solved via a unit of work, but I'm not sure if this is an approach worth pursuing.
What else am I missing here? :)
--
You received this message because you are subscribed to the Google Groups "DDD/CQRS" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dddcqrs+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
So I'm starting to see the reasoning behind this. I'm just put off by the often associated explanation that such things are events only, not commands, because they cannot fail.
The user must, within a brief time-window, be alerted that the action he just performed is not allowed
The user must, within a brief time-window, be alerted that the action he just performed is not allowed
Maybe "requires remediation" in place of "not allowed"? The arrow of time is going thataway.