Re: When and where to raise AggregateRootAddedEvent
"Moran Lefler" <[email protected]>
| Newsgroups | gmane.comp.programming.domain-driven-design |
|---|---|
| Message-ID | <[email protected]> |
That's actually a very clever solution! I like how responsibilities are neatly separated between the domain model and the app logic - the domain model does not need to know anything about event publishing infrastructure, and the app doesn't need to know which concrete events to publish or when to publish them. I will definitely try it out, thanks! --- In [email protected], Johan Haleby <johan.haleby@...> wrote: > > I think one interesting approach is to return events from your aggregates > instead of publishing them as described by this > blog<http://www.jayway.com/2013/06/20/dont-publish-domain-events-return-them/> > . > > Regards, > /Johan > > > On Mon, Jun 24, 2013 at 9:35 PM, Moran Lefler <moranlf@...> wrote: > > > ** > > > > > > The point that you are raising bugs me as well. > > I see it as a more general concern, since the same question can be asked > > about any change of state within the domain model - Do we raise the domain > > event as soon as the model changes, or only when the change is actually > > committed to the store? As you mention, triggering the event from the > > domain model may cause other handlers to act upon that knowledge, querying > > stale data from the db, and even may in turn trigger other events and so on > > - think of all the compensation logic that have to rollback all of that > > action, in case of a e.g. a transaction failure. > > > > I would very much like to hear the group's opinion on that matter. > > > > Cheers, > > Moran > > > > > > --- In [email protected], Wim van Gool <vangool.w@> > > wrote: > > > > > > While implementing my example DDD-project, there's one thing that's still > > > not very clear to me at this point, mainly because I see so many samples > > > and advise that contradict each other or sometimes raise more questions > > > than they answer. Yet, ironically, it's actually core to implementing a > > > DDD-application, IMHO. > > > > > > Suppose I must add/create a new aggregate, what thing is responsible for > > > raising the *NewAggregateAddedEvent*, and when to raise it? Note that I'm > > > > > not applying event-sourcing; I just use plain state-based aggregates and > > > repositories. > > > > > > *Option 1: Let your ApplicationService/MessageHandler take care of it* > > > > > One way of doing this is the most simple thing, something like this: > > > > > > public sealed class AddNewCarHandler : IMessageHandler<AddNewCarCommand> > > > { > > > private readonly ICarRepository _repository; > > > > > > .... > > > > > > public void Handle(AddNewCarCommand command) > > > { > > > // Create the new Car somehow > > > Car newCar = _carFactory.AssembleNewCar(...); > > > > > > _repository.Add(newCar); > > > > > > DomainEventBus.Publish(new ...()); > > > } > > > } > > > > > > This is the way I have been doing it so far. The advantage of doing it > > this > > > way is that it's pretty straightforward and simple. The downside is that > > I > > > now my application-layer is raising domain events, which is not something > > > that it's 'supposed to do' I guess. That's why I'm questioning this > > > approach. > > > > > > *Option 2: Let your factory-method publish the event* > > > > > This is the way Vaughn Vernon explains it is his book (paragraph on > > > creating Discussion instances), which basically means that, in my own > > > example, method AssembleNewCar() would call DomainEventBus.Publish(..) > > > inside before returning. > > > > > > The advantage of doing it this way is that domain events are only raised > > > inside the domain, but there's a caveat that I see here: the domain event > > > is now raised *before* the aggregate (Car in this case) is actually added > > > > > to the repository. If you have hooked up any handlers that get invoked > > > within the same transaction, they might expect the new aggregate to be > > > present in the repository and attempt to retrieve it. If having such > > > handlers in the first place is a smell in itself I'd like to here this > > > though... Moreover, this problem could be tackled by attaching the newly > > > created aggregate to the created event, but I'd like to avoid this if > > > possible and only communicate using id's where I can. > > > > > > *Option 3: Create a domain-service.* > > > > > Another option that tackles both 'problems' of the two above is to > > create a > > > separate domain service like AddNewCarService to your domain and let the > > > application-service basically delegate it's work to this service - with > > the > > > exception of translating the command to appropriate domain-values/objects > > > of course. Needless to say, this does require extra domain services to be > > > created for the sole purpose of adding new aggregates, which I haven't > > seen > > > much in code samples and so makes me think this is not a typical > > > (desirable?) way of doing things. > > > > > > So, how are you guys doing this? > > > > > > > > > > ------------------------------------