I have a project in which I use some domain models. The ID for those models is deterministic and depends only on the content of the object. Two property-wise identical objects will have the same ID. This is true for any object of my model.
This computation is recursive, meaning that it goes through the references and incorporate their own ID into the computation. It's basically a merkle tree.
For example if I have a class A and B as follow:
public class A {
public string Value { get; }
public B RefToB { get; }
}
Then I will compute the ID of RefToB then serialize everthing into bytes then compute the SHA1 of this byte array in order to get another byte array which will be my definitive id.
I will store the bytes of the object using the computed SHA1 into a custom KeyValue storage specifically made to my purpose.
This allows me to compare subtrees very easily.
Now, I don't want to add the possibility to build an invalid model object so I can't add an byte[] id
parameter into the constructor since is a computed value.
I use DTO <=> model mappings and my store uses the DTOs to compute the IDs and store the data.
I try to stick to an hexagonal architecture meaning that I have a Persistence project and a Domain model project, domain has no dependencies.
The question is: I feel that I'm doing a wrong design but I can't come up with a good explanation of my wrong-doing. Do you think I should do this design differently?