0

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?

Ephasme
  • 212
  • 1
  • 9

1 Answers1

0

If you are going to make a value object, meaning the content of your object is immutable, then this value object should internally generate this ID. This is part of your domain and this is business logic, so it have to be part of your value object.

In java, its like a hashCode, it is calculated inside the object.

Its not your DTO job to do that, its your own object. By doing that you make them more correct, impossible to hack and pass a wrong value which would invalidate your model, and also easier to test: Create two different object with the same values, and check their ID are equals. Very easy !

If you are going for mutable objects the same apply, just compute your ID on the fly instead of at the instance creation in the constructor.

Sylvain Lecoy
  • 762
  • 5
  • 14