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?
>
>
>  
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.