user2153675
user2153675

Reputation: 103

DDD aggregate roots

I have question regarding and bounded contexts.

Suppose there are two bounded contexts. In the first one the aggregate root is Customer who is able to publish an advertisement on a webpage. I suppose that falls in his behavior, in turn he has a method of PublishAdvertisement(). But the second bounded context has Advertisement as aggregate. That imposes that Advertisement has a Customer property, due to its nature of belonging to a Customer.

Both Customer and Advertisement are unique in the system and database.

My question is: Is it advisable to delegate the creation of Advertisement from Customer to a factory or dependency injection?

Edit:

I thank you for your answers and apologize for the lack of info.

Dependency injection:

I was wondering what is the best manner to resolve a given situation. The company has a Stock of Advert templates, if a template is in stock its good for use, if it's not, then it's rented to someone. The company has a plan on having more Stocks. If a Customer wants to make an advert in these templates he chooses a template and if its in stock all is good to go. Reading this as it is I assumed that there should be a service(domain) CheckAvailability(template), due to the nature of the service it does not fit in a specific aggregate because it uses several aggregates with validations and queries the database. In future when there would be more Stocks(some rented from other companies, maybe someone else's database), I was planing on using dependency injection to add these Stocks to the service without changing the implementation. Question is , does this seem as a good idea?

Bounded contexts:

In regards to bounded contexts and database. Yes, there is one database object and two contexts that use the same database object. Order has a reference to Customer, due to belonging to a Customer, looks something like this

Order() Customer customer(get; private set;)

///other properties and methods

I would appreciate any additional information via link, video, book in terms of implications of having 2 contexts like these (Customer->Order___1:M) relate to the same database. Thank you.

Upvotes: 1

Views: 346

Answers (3)

guillaume31
guillaume31

Reputation: 14064

What are the customer related invariants enforced by Customer.PublishAdvertisement() ?

  • If there aren't any, you'll be better off moving that method to the Advertisement aggregate root in the other BC, perhaps making it a constructor or to an AdvertisementFactory if the construction logic is complex. Just because the physical world user who creates an ad is a Customer doesn't automatically imply that their aggregate root should have that method. The ad creation process can stay in the Advertisement BC, with an Advertisement application service as the entry point.

  • If there are, then Customer could emit an AdvertisementPublished event that the Advertisement BC subscribes to. You should be aware though that if you follow the "aggregate as consistency boundary" good practice, Customer can't be immediately consistent with Advertisement which means that there can be a delay and inconsistencies can be introduced between when the event is emitted and when the Advertisement is persisted and thus visible to other clients.

    It is usually not an issue when you are creating a new AR, but keep in mind that the state of the Customer that checked the invariants and decided to create the Advertisement can change and the invariants be violated in the mean time, before Advertisement is persisted.

    Obviously, given that the 2 BCs share a common database (which is probably not a good idea as @theDmi pointed out), you could decide to break that rule and make your transaction span across the 2 aggregates. Not necessarily that bad if you just persist a new Advertisement and not modify one that can potentially be accessed concurrently.

As far as dependency injection, I can't see the connection here -- what is the dependency to be injected ?

Upvotes: 1

theDmi
theDmi

Reputation: 18024

Both Customer and Advertisement are unique in the system and database.

If that is the case, then having these concepts in two bounded contexts that use the same DB objects is a problem! The separation between two bounded contexts is a strong one, so they shouldn't communicate by changing the same DB object.

So I think you have some major design issues there. Try to fix them first by creating a model that corresponds to the real-world problem, discuss it with your domain experts.

And now to answer your main question:

Creating entities through factories is a good idea. The factory hides the (potentially complex) mechanism to create an entity and provide it with the required services. The factory receives these services through DI in the first place, and can forward them to the entity during instantiation.

Upvotes: 2

Matías Fidemraizer
Matías Fidemraizer

Reputation: 64933

Absolutely.

One thing is associating domain objects and another thing is working with them. An ad has some associated customer, and the customer and ad must be created in their respective domain layers (i.e. repository and service at least...).

This is separating concerns in the right way, since you don't want customers to be created where ads are also created and vice versa.

I guess you already know the single responsibility principle.

Upvotes: 1

Related Questions