Oops, ja das bin ich noch schuldig
Gibt es eine Fausregel, wie man hier generell vorgeht?
Meinst Du bzgl. der Bildung von Aggregates? Die sind für mich Transaktionseinheiten und gewissermaßen "Wächter über Geschäftsregeln". Dazu ein Beispiel: Du hast die Regel, dass Material an einem Lagerort nur an einem Lagerplatz liegen kann. Das kann weder Material noch MaterialStock durchsetzen. Du brauchst also etwas, das den Überblick über das Lager hat - hier bietet sich StorageLocation an.
Wenn Du eine weitere Regel hast, die über mehrere StorageLocations hinweg gilt, musst Du die wieder in etwas unterbringen, das den Überblick über StorageLocations besitzt - ggf. beispielsweise in einem DomainService.
Ich hätte MaterialBooking eher als ValueObject gesehen
Das kann durchaus sein. Wenn Du Dich später nicht mehr auf eine einzelne Buchung beziehen musst (oh, Buchung 0815 war fehlerhaft), sondern MaterialBooking nur als Ereignis betrachtest, das ggf. noch nicht einmal gespeichert wird, dann handelt es sich natürlich nicht um eine Entity. Es sind auch weitere Fälle vorstellbar: z. B. könnte man MaterialBooking selbst als VO modellieren und für z. B. eine Buchungshistorie eine Entity einführen, die ihrerseits als Wert MaterialBooking bekommt.
Was besser ist? KA - das stellt sich im Verlauf noch raus; man wird beim Modell nicht zum letzten Mal den Stift angelegt haben.
Ähnlich ist es bei MaterialStock (wobei es hier die "lokale Identität" durch die MaterialId innerhalb einer StorageLocation gibt)
MaterialStock ist ganz klar eine Entity.
Nehmen wir an, Du hättest für die Lagerplätze "Bestandszettel". Wenn Du am Bestand etwas ändern willst, musst Du das im zugehörigen(!) Bestandszettel ändern. Dazu muss jeder einzelne Zettel von jedem anderen Zettel unterscheidbar sein. Bei einer Änderung brauchst Du einen ganz bestimmten Zettel und nur diesen. Bevor ich mich jetzt "verzettel", kurz: MaterialStock hat Identität -> Entity