Re: [DDD/CQRS] Can one aggregate root create an instance of another?

2,224 views
Skip to first unread message

Greg Young

unread,
Oct 12, 2012, 4:46:31 AM10/12/12
to ddd...@googlegroups.com
yes 100% ok! very very common.

On Tue, Oct 9, 2012 at 7:16 PM, @nbarnwell <mai...@neilbarnwell.co.uk> wrote:
> I'm re-reading Udi's post on Don't Create Aggregate Roots and wondering how
> far to take it.
>
> He basically says you shouldn't do stuff like this (emphasis mine):
>
> SalesOrder o = new SalesOrder();
> // Set properties, add line items etc
> repository.Save(o);
>
> but instead should accept that the SalesOrder comes from something else,
> where that "somewhere else" is responsible for "newing-up" the actual order
> object. Perhaps:
>
> Customer c = repository.Get<Customer>(message.CustomerId);
> SalesOrder o = c.PlaceOrder(message.BasketItems, message.DeliveryAddress
> ...);
> repository.Save(o);
>
> However, I'm not certain that it's appropriate in this case to say that the
> SalesOrder is actually part of the Customer aggregate, is it? If I were
> modelling this as a document in a document DB, for example.
>
> So is it okay for an AR to effectively be a factory for other ARs?
>
> Many thanks in advance,
>
> Neil.
>
> Neil Barnwell.
> Twitter: @neilbarnwell
> web: http://www.neilbarnwell.co.uk



--
Le doute n'est pas une condition agréable, mais la certitude est absurde.

Hajdrik Attila

unread,
Oct 12, 2012, 9:54:39 AM10/12/12
to ddd...@googlegroups.com
In my case when I had a discussion about something similar, regarding the
containment of client / contracts I'm also going this way: contracts are
under client, and in the domain code, the client class can instantiate a
contract based on the incoming data from the command which will be
attached to him in the storage layer as an embedded document.
________________________________

Sent from Exchange Server 2013

@yreynhout

unread,
Oct 13, 2012, 6:03:23 AM10/13/12
to ddd...@googlegroups.com
+1. This is very common for a simple reason: it's an opportunity to get at the internal state of the other AR and copy whatever data is necessary at the beginning of lifecycle of the new AR. Things you would otherwise "invent" a read model for, to query during command execution. Things you would otherwise put in the command (performing the copy of information in the user interface - information, in the end, coming from a read model). Don't get me wrong, there's trade-offs to be made in each case. Sometimes it's better to copy into the command, because the end-user wants a WYSIWYG experience. Sometimes it's a side-effect (i.e. the copying of data), the end-user is not particularly concerned with, but one that does benefit/fit the use case at hand. Good old "it depends".
Coincidentally - as I recently published a post on this subject - you might want to look into "object inheritance" (from Streamlined Object modeling).

On Friday, October 12, 2012 10:46:34 AM UTC+2, Greg Young wrote:
yes 100% ok! very very common.

Franck

unread,
Oct 13, 2012, 10:28:05 AM10/13/12
to ddd...@googlegroups.com
I got a similar situation and I still don't know how to deal with it. The behavior I want to model is the fact that a customer can pay an invoice. Seems pretty harmless but I spotted 3 ways of doing this:

1- customer AR has a PayInvoice method which get the invoice as a parameter and then this customer becomes the creator of the payment entity with all the relevant customer information. Now within this situation I got 2 other ways of doing this.

1.1- This PayInvoice method also gets the PaymentProcessor service which the customer calls the ProcessPayment method on.
1.2- This PayInvoice method only creates the payment entity with the customer information and returns the payment.

2- The customer doesn't have a PayInvoice method and everything gets done in the PaymentProcessor service.

So I got 3 ways of doing this. The question is, is it DDDish to give ARs services as parameters in order to get the job done or is it the other way around and the services should get the customer as a parameter?

I may be hijacking this question a little but it seems to right place to continue asking questions about object dependencies.

Marijn Huizendveld

unread,
Oct 13, 2012, 11:12:40 AM10/13/12
to ddd...@googlegroups.com
As far as I know it is ok to have your AR methods rely on a service interface for handling a command. 

Verstuurd vanaf mijn iPhone

Franck

unread,
Oct 14, 2012, 2:41:51 PM10/14/12
to ddd...@googlegroups.com
Yes but I don't know how much 'far' I want to go in terms of putting behavior (and dependencies) in AR. In my situation, I need the payment processor more for acting as the continuation of the operation and not because I need data from it in order to do stuff. The more I think about it, the more I see the customer as only 'preparing' the payment with the customer's information. So the question is, what's the best choice between:

1- command arrives at handler
        grab customer, invoice with ids in command
        resolve order processor
        prepare payment from customer
        orderProcessor.processPayment(invoice, payment)

2- command arrives at handler
        grab customer, invoice with ids in command
        resolve order processor
        customer.payInvoice(invoice, order processor)

It just seems I'm overloading / coupling the customer with the order processor.
Any thoughts?

@nbarnwell

unread,
Oct 15, 2012, 4:26:02 AM10/15/12
to ddd...@googlegroups.com
Brilliant, thanks. I thought as much but couldn't articulate it properly. My concern was one AR creating something that was itself not part of that AR. It seemed highly likely based on my understanding of the blue book and other materials, but there's nothing like asking a direct question to quell any doubts. :)
Reply all
Reply to author
Forward
0 new messages