So for DDD folks there, Aggregate Roots are supposed to contain business logics only and exposed what is needed only.
In DDD Red Book by Vaugh Vernon, he used LevelDB and Hibernate as examples. LevelDB is key-value storage and Hibernate I think uses reflection.
However, if I don't want to use any of those, how am I going to save Aggregates?
3 of the easiest solutions I can think of are listed in the title:
- Exposed public getters
- Reflection
- Inject repository to aggregate and have a method called save (Memento pattern?)
Let's imagine Payments:
- CardPayment with cardNumber, expiration, cardHolderName
- CashPayment with cashAmount
- PaypalPayment with paypalAccountId
Each of those has their own unique properties but adheres to an abstract class/interface (won't go deeper for simplicity).
In my whole life, there are cases like this that can't be avoided especially when doing Repository where you really need to know what are you going to save.
Going with public getters, you might need to do an instanceOf checks in repository so you can cast and access the unique properties.
Going with reflection, it may not be a problem but feels like a hack...
Injecting repositoryObj to a save
method seems to be the next best option, at least the Aggregate knows what properties to save but this violates DDD I think. It knows about persistence too much and save
is not part of ubiquitous language.
I can be pragmatic and eat a cake but I want to know how it is done the pure OOP and/or DDD way.
EDIT:
Found an article from Vaughn Vernon on how to model Aggregates with Entity Framework. The article can be applied to anything else too, it's not really specific to EF. I'll just link to it to prevent longer O.P: https://kalele.io/blog-posts/modeling-aggregates-with-ddd-and-entity-framework/