Interface function IEntityRepository::Get is returning an optional reference to query an IEntity.
1. Use optional reference as return value for IEntity query.
In order to check whether an IEntity with a certain name/id exists, function IEntityRepository::Contains could be used to query this information. If IEntityRepository::Get is called on a non-existing name/id, the function would throw, so for defensive programming reasons a IEntityRepository::Contains should always be done before actually calling IEntityRepository::Get. The good thing about plain old C-pointers is that assignment and existence check can be done in one call. Since C++17 the same functionality is managed by std::optional.
Another disadvantage of using a plain reference to IEntity is when it is used as a class member, where it needs to be initialized when an object of that class is defined. It might be that during construction time this IEntity is not known/existing yet. Of cource, a plain old C-pointer could be used in this case, but it wouldn't be a consistant usage.
The proposal is to use std::optional<std::reference_wrapper> as return value for IEntityRepository::Get.
2. Possibility to register functions that are called on entity creatiion/deletion.
If scenario domain entities are having references to the same IEntity, it might be that another instance is deleting this IEntity invalidating all references pointing to it. Those situations could be handled using the callback mechanism.
The program was tested solely for our own use cases, which might differ from yours.
Jupp Tscheak email@example.com, Mercedes-Benz AG on behalf of Daimler TSS GmbH