Re: When and where to raise AggregateRootAddedEvent
Dennis Traub <[email protected]>
| Newsgroups | gmane.comp.programming.domain-driven-design |
|---|---|
| Message-ID | <CAJw46f71LmTyKyg7+R-zNj_NHtniBc-LbgPN35-=1prdAgLXNw@mail.gmail.com> |
Hi Wim,
how about raising it in the constructor of the respective Aggregate Root?
class Car {
public Car(Model model, Make make, FrameNumber frameNumber) {
this.Apply(new CarManufactured(...));
}
}
--
Dennis Traub
Software Development Consultancy
Am Bogen 7
33178 Borchen
Phone: 05293/73942-73
Fax: 05293/73942-74
Mobile: 0170/2842385
Mail: [email protected] <[email protected]>
On Mon, Jun 24, 2013 at 8:27 PM, Wim van Gool <[email protected]> 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?
>
>
>
>