I create an application based on DDD and hexagonal architecture in conjunction with CQRS (without ES).
I'm stuck.
In one of the bounded contexts I have layers:
- Domain,
- Application,
- Infrastructure,
- Ui.
I think this is a fairly common solution.
Currently, no element of the application goes beyond its layer. I believe that I distributed everything wisely, according to all recommendations.
Therefore, I am not going to describe here what is contained in a given layer.
However, I have a big problem to find the right place for certain elements.
And so what to do with the classes generating slugs and UUID?
Perhaps I know too little, but based on the knowledge gathered, I do not see any place for them in any of the above layers. Also, I wouldn't like to create something like 'shared' or 'common' layer. For the moment I stopped at the solution to create interfaces for them in the application, and leave the implementation to the infrastructure.
Another thing that bothers me: I have Alert entity. It is responsible for displaying notifications in the system. Some of them are randomly generated based on categories. As I use CQRS, the notification generator gets alerts not from the domain but as query models.
So which layer is suitable for such a generator? Can such a generator be considered a service?
I am counting on help.
yeah why not. your solution sounds solid. especially if the application does not need to know the nature of the ID generation.
eg
UUIDGenerator
implementsIdGenerator
. the contract in application only specifies that it has to have "identity" properties.I felt that, while "infrastructure" is a collection of all low level implementations of the other layers, and your implementation may reside there - common code that does not communicate with external systems and rather is some "library-like" code is sometimes packaged in a "util" package/module and used directly from everywhere as if was in the standard lib.
question is - do you really need dynamic dispatch like the interface-implementation relationship above? or is it rather a static call to a function
generateId
?