Does this make sense or what is wrong with this approach?
So instead of using event store, we may use aggregate repository to update the aggregate based on values contained in published event.
Does this make sense or what is wrong with this approach?
So instead of using event store, we may use aggregate repository to update the aggregate based on values contained in published event.
Does this make sense or what is wrong with this approach?
At surface level, the diagram looks pretty broken. It's hard to say, because your diagram doesn't describe the context of the publish call.
What the diagram appears to imply is that, instead of copying the in memory state of the aggregate directly to the repository, we're going to first decompose that state into events, copy them to a message transport layer, addressed to the repository, who will then rebuild a copy of the state of the aggregate that we originally started with?
That's a lot of complexity to introduce - where do you think the payoff is going to happen?
What you might be looking for is Udi Dahan's approach to handling domain events, which writes the events and the updated aggregate state into the database together.
His approach doesn't really change the basic pattern very much - the application component uses the repository to obtain a local copy of the state to interact with, and when done attempts to commit its changes to the repository. It's the repository code at that point that extract both the state and domain events from the aggregate before writing them to the database.
Note that, in Udi's pattern, the publish of the event happens after the durable write the database has succeeded.
Aggregate -->
Repository -->
DataStore -->
Domain Event Publisher -->
Subscribers
would be the more usual flow; that might possibly include the repository (or the application) publishing the domain events after the data store as confirmed the successful commit of the transaction.
In any event, I don't recognize from your diagram a problem that you should be trying to solve; it looks like an improvisation from the usual patterns, and without more context it is difficult to diagnose whether there is a fundamental misunderstanding or a really unusual set of constraints that are distorting the solution.
It might be worth opening a new question describing the problem you are trying to solve, and the constraints that need to be satisfied, to see if anyone is aware of relevant literature.
Updating data from events even when you are not using event sourcing is fine, your approach is fine. But your approach depends entirely on your needs and what exactly the updates are. The reason why people use event sourcing is to have the event log. But you usually do not need the event log for every single thing in your project, as you have already noticed.
When you are not using event sourcing and are not going to be using the event log at all, you should ask yourself whether you needs events at all?
For the simple update you are demonstrating here, the event is pretty much meaningless and the update can be made by using values from the aggregate directly. Adding the event just because is an unnecessary overhead.
However, there is a use case for domain events.
Let's say that you have some aggregate which has 4 methods to allow modifications. When you run three out of the four methods to modify the inner state of the aggregate, all you need to do is to update the aggregate in the data layer as well. But when you run the fourth method, after persisting the aggregate you also want to start some process as a reaction to the operation.
This specific case is very well and neatly modeled using domain events. You subscribe to your event bus to react only on the event generated by the fourth method and ignore the other three. The design is cohesive and sleek.
Obviously, using domain events like this will force you to update the data layer from the data contained within the events themselves, as you have demonstrated in the picture.
I would not recommend using events just because they sound cool. Use them at appropriate places and when you really need them. If you don't, using simple mutators to update properties of an aggregate directly is completely fine.
I think the design is wrong for a general use case. From the comments I understand that the state would be build by the Repository. This is wrong because the logic to update the state should stay in the same place that query the state, so it should also be contained in the Aggregate. Put it other way, the Repository implementation would contain business/domain logic and this is not OK.
If you don't want to use an Event store then you can use CQRS with a flat persistence.