@Mark,
If you're just querying data, you could potentially do that outside of
the domain first and then pass it into the domain. But if the
external service is doing something, then there are a few more things
to consider. Let me project from your original question and modify
the intent somewhat to that of an external service call that does
something, not just querying data...
If you're using event sourcing for #1, it will get the job done, but
you might run into problems during failure conditions. Specifically,
what happens if the command is related to charging someone's credit
card. Let's suppose that you process the command, charge their card,
and before you commit the associated event(s), the machine dies for
whatever reason. When it comes back online you'll process the command
again and charge their card. Bad.
With #2, you can be a little bit more flexible. The aggregate makes
the decision whether the card should be charged and/or how much to
charge. The saga tracks the state of the entire process (which might
be charging a card and then shipping an item). Then, the handler that
receives the message to charge the card has a few options. Prior to
charging a card, it can write a local value saying, "I'm about to
charge card X $123 for order Y. If at any point the process fails,
you'll know when you resume. And if you detect a failure when you
resume, you can query the WCF service to determine if the card was
charged or not.
Granted, all of this could be done inside of ISomeService using double
dispatch off the domain, but #2 breaks up the transactional boundaries
and makes each step more explicit thus giving you fine-grained control
over the entire process. #2 makes the error conditions more explicit
and forces you to deal with them in the form of events back to the
saga.
As far as "more code to maintain" is concerned, you might have a few
more command and event classes, but they are well-named classes that
express intent and have *no* behavior. They're simple DTOs that can
be serialized and transferred across the wire. You may also have one
additional message handler that receives the message and passes it to
your ISomeService, but that's about it.
Also, in #1, how do you deal with timeouts? What about optimistic
concurrency for when an external WCF call takes 10-20 seconds but
another message has been received by the aggregate in the meantime?
When you go to save the results of the WCF call, you'll get an
optimistic concurrency exception and unless you're doing "event
merging" which is an advanced event sourcing concept, you'll throw
away the results of your WCF call and retry the command.
On Oct 6, 3:56 am, Think Before Coding <
jeremie.chassa...@gmail.com>
wrote: