Domain Driven Design and SaveAll()

D

Daniel C

In our domain driven design, we allow clients to consume a service
that includes a "Save Step" method (public Step SaveStep(Step
userStep). This works great for the consumers of the web service
(easy call, just send back entire step object) and for persisting the
step data to the data store (just send the step to the repos).

It gets a little more complicated when we introduce the idea that
SaveStep should, in addition to persisting data, trigger a specific
event that is captured by an outside process, such as a workflow
engine. A Step in this case is somewhat complex; a collection of
users, collection of documents, and permissions per user on the
documents. We need to trigger events such as user added, removed,
permission set added/removed, etc. Is there a best practice/pattern/
example to approaching this; basically, comparing the passed in step
to the persisted step and generating what has changed?

I could obviously write a very specific algo to compare the saved and
new steps, with hard-coded references to each component in the
Step...but this would be ugly and not very adaptable to changes in the
Step in the future.
 
P

Pavel Minaev

Daniel C said:
In our domain driven design, we allow clients to consume a service
that includes a "Save Step" method (public Step SaveStep(Step
userStep). This works great for the consumers of the web service
(easy call, just send back entire step object) and for persisting the
step data to the data store (just send the step to the repos).

It gets a little more complicated when we introduce the idea that
SaveStep should, in addition to persisting data, trigger a specific
event that is captured by an outside process, such as a workflow
engine. A Step in this case is somewhat complex; a collection of
users, collection of documents, and permissions per user on the
documents. We need to trigger events such as user added, removed,
permission set added/removed, etc. Is there a best practice/pattern/
example to approaching this; basically, comparing the passed in step
to the persisted step and generating what has changed?

I could obviously write a very specific algo to compare the saved and
new steps, with hard-coded references to each component in the
Step...but this would be ugly and not very adaptable to changes in the
Step in the future.

If you're essentially comparing two objects for deep equality, then I see
nothing wrong with providing your own interface - IDiffable? - dimilar to
IEquatable for this, and using it, calling the corresponding method
recursively on child objects as needed. You'll still have component-specific
comparison code, but it will be neatly organized, with each
component-specific part belonging to IDiffable implementation of that
specific component; so any changes are always localized (changed component
members - change its IDiffable too). In practice, this approach is likely to
be more maintainable as any other alternative, too, because intent of the
code is very clear.

Otherwise, you could go the metaprogramming way, and use custom attributes
to mark fields in your classes as participating in the diff, and then
reflection to traverse the object graph and perform a general comparison. In
practice, this may be tricky to get right in less trivial cases, because
you'll need to special-case a lot of things which can't be just compared
field-by-field (strings, collections...).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top