Re: When and where to raise AggregateRootAddedEvent
Greg Young <[email protected]>
| Newsgroups | gmane.comp.programming.domain-driven-design |
|---|---|
| Message-ID | <CAC9RQti_DFSC9XNNNb1e+KixQFZUs9f9BAySdb7XSe8DWakZ+Q@mail.gmail.com> |
This is how simplecqrs handles it. Having a factory method do it is
generally a bad idea as now you need a transactional context managed.
On Monday, June 24, 2013, Dennis Traub wrote:
> **
>
>
> 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] <javascript:_e({}, 'cvml',
> '[email protected]');>
>
>
> On Mon, Jun 24, 2013 at 8:27 PM, Wim van Gool <[email protected]<javascript:_e({}, 'cvml', '[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?
>>
>>
>>
>
>
--
Le doute n'est pas une condition agréable, mais la certitude est absurde.