Search code examples
domain-driven-designddd-repositories

DDD how to generate unique address in model without checking persistent layer?


I have an Address model in my domain which has some complex logic for address generation (imagine similar to IBAN), but since the address is quite short there may be some collision to already existing addresses stored in database. Since there is an established practice that models should not access repositories how could this be accomplished? Should I make an instance in service layer and then check it against repository?


Solution

  • Every domain use case is technically a service. When you need to add a new Address, just create the object then verify if something similar exists.

    In your service you can use a query that will check if the address exists. If you want it to be a repository method, then it means Address is an entity. However, be aware that the uniqueness is a business constraint and maybe it shouldn't be hidden inside the repository. I prefer to be clearly expressed inside the CreateAddress use case.

    There is a catch though, everything in your service needs to be idempotent. If the app crashes and the command is handled again we need to be able to detect if it's a duplicate operation. Meh.. it sounds complicated but it's not hard once you've done it once.

    Personally, I have a 'uniques' storage (which happens to use the database to ensure the constraint) where I put a value like [object_type+unique_property] and if it exists it returns false, if not it adds it to the storage. It's generic enough to work with any entity and it's idempotent as well.