Re: Validation in CQRS Journey Conference project
"wonderfulworldofpingpong" <[email protected]>
| Newsgroups | gmane.comp.programming.domain-driven-design |
|---|---|
| Message-ID | <[email protected]> |
Since I did not receive a response for a while, I thought to shed some
light on the issue with this implementation.
The problem I see with this implementation is that the CreateConference
does not log the CreateConference event. Consider the situation where
the user has deleted the Conference having the same slug he created
already. Now the user has to come back and do the CreateConference again
with the same information he tried to enter in his first attempt to
create it. He failed at that time because the same slug existed at that
time. If the CreateConference event was stored, and is sourced from the
EventStore again and replayed, the user does not have to enter the same
data again. With this approach, I'm looking at the following commands
and events.
* RequestConferenceCreationCommand - always wins
* RequestConferenceCreationEvent - always wins
* ConferenceValidatedEvent - Win or Fail based on the validation in
other Bounded Contexts
* ConferenceCreatedEvent - Win or Fail
The RequestConferenceCreationCommand sends a
RequestConferenceCreationEvent. This event is processed by the Bounded
Contexts that can validate the business rules. When all those Bounded
Contexts pass the validation, they send ConferenceValidateEvent. In this
validation success event, the persistence of the conference object
happens. Then the ConferenceCreatedEvent is broadcasted.
One problem I see with my approach is the events synchronizing from
multiple Bounded Contexts to decided on all the Business Rules are
passed. In this situation one Bounded Context which is listening from
multiple Bounded Contexts that are doing the validation.
Let me know what you think.
--- In [email protected], "wonderfulworldofpingpong"
wrote:
>
>
> The following code (in yellow background) is taken from the CQRS
Journey
> project . In
> this code, a conference can be created in the Conference Bounded
> Context. No CQRS is being used here but simple CRUD.
>
> You can see a validation happening in this snippet of code in the
> CreateConference which is part of the Conference Service. If there is
> already an existing slug, the method throws an exception. This is a
> simple validation, so doing a validation at the service level may be
> okay. But we can make an argument that the validation has now leaked
to
> the service.
>
> In real applications, in the place of checking for duplicate slug,
there
> would be complicated validation logic. Also, the Conference BC may
have
> to talk to other Bounded Contexts to decide on whether the conference
> can be created.
>
> My question is, how do we handle the creation of a conference with
> validation by talking to other Bounded Contexts? (1) Is it okay for
the
> following method / command wait until the other BC returns with the
> validation status? The operation is synchronous. If the validation
from
> the other Bounded Context is true, then continue creating the
> conference. (2) Instead of making this as synchronous, the Conference
> service in this method / command, send a validation command to the
other
> Bounded Context. Then in the HandleEvent, create the conference. This
> approach can scale.
>
> public void CreateConference(ConferenceInfo conference)
> {
> using (var context = new
> ConferenceContext(this.nameOrConnectionString))
> {
> var existingSlug = this.retryPolicy.ExecuteAction(() =>
> context.Conferences
> .Where(c => c.Slug == conference.Slug)
> .Select(c => c.Slug)
> .Any());
>
> if (existingSlug)
> throw new DuplicateNameException("The chosen
> conference slug is already taken.");
>
> // Conference publishing is explicit.
> if (conference.IsPublished)
> conference.IsPublished = false;
>
> context.Conferences.Add(conference);
> this.retryPolicy.ExecuteAction(() =>
> context.SaveChanges());
>
>
> this.PublishConferenceEvent (conference);
> }
> }
>