Domain-Driven Design
> >
AggregateRelationshipsAndUnitOfWork

Forgive me if this topic is becoming tedious - I have browsed through
the messages on this list and couldnt see what I was looking for. If
I end up repeating something already mentioned recently, forgive me.
I dont have my DDD book at hand either, so I am trying to formulate
my ideas from memory too.

Currently, the system I am working on has a good concept of
Aggregates, and our persistence (in .NET) is using mappers which is
working well. However, we have to move to some form of Unit of Work
now, as our domain model is getting complex, and during both a
business or system transaction, tracking changes is complex.

As far as I can remember, Aggregate Roots are the only things that
have a Repository (I say are the Only things, but I appreciate it
depends on the context). From recent discussions, I kinda got the
feeling the sentiments where that a Repository is a distinct concept
that isnt necessarily a Mapper. This is where I run into trouble.

We have implemented a UOW based on Fowlers P4EA. As each object
becomes dirty, it registers with the UOW, and eventually the UOW will
commit() via a loop that calls onto a bunch of Mappers. If we have:

A.Root -------> B
| 0..*
|
-----------> C
1..10

If B is modified, then currently a call to the UOW ensues. But given
the transactional aspect of Aggregates and Roots, how does this fit
in? Even if A is always the root to be persisted, there must still
be some ability to discern creations from updates from deletes within
the object graph. Am I missing something?

Again I apologise if this is going over previously covered ground. I
will dig my DDD book out tonight.

Thanks,

Addendum:

This could be more a technical issue, and I hope it doesnt detract from the
purpose of this list
being more about DDD.

I have an class named Extraction which has a bunch of IStudy references:

Extraction --------> IStudy
0..*

IStudy is defined in some package/namespace elsewhere. The way these are used
is simple - a user
defines all the studies an extraction is for. These get stored against the
extraction. Using
Aggregates things are pretty simple - in the mapper, the study references are
cleared and
re-inserted during an Update to Extraction. But this isnt the ideal. Using a
UOW paradigm, I am
finding it difficult to see how I could possibly work with an IStudy unless I
did this:

Extraction --------> ExtractionStudy -------->IStudy
0..* 1 1

If Extraction(E1).Studies = (s1, s2, s3, s4, s5) before, and s3 is removed, the
UOW needs to
somehow know that s3 for E1 must be removed. It seems clear that it isnt IStudy
that deals with
the registration of a remove/delete to the UOW. It is probably the collection
of IStudy
references, or indeed just the Extraction object. But, UOW works on the basis
of a class has an
ID that is used to persist the dirty/removed object. This technique falls over
unless
ExtractionStudy is introduced. But I dont like this solution, and it still
doesnt deal with
Aggregates very well.

Hoping this all makes sense...

NickRobinson



This is a good example of where a framework to support aggregates
really helps. If you had the means to declare the aggregate, saying
that Extraction(E1) was the root and that Studies (s1, s2) are
contained within it, then when E1 was removed in a UOW, all elements
of its aggregate could automatically be traced and also slated for
removal. Such frameworks are nontrivial to build, but then the
problem they solve for the app developers is nontrivial also.

EricEvans


Hi Eric,

After reading some of the posts from Randy, Patrick and others about persistence
in Gemstone and
JDO etc, I feel frustrated with .NET. I am hopeful ObjectSpaces will bring much
more to the table
for OO development in .NET. But, given that no such framework exists, what do
people think about
the extra class I introduced (ExtractionStudy)? Is this a bad technique? When I
think of othr
scenarios, the first that comes to mind is the Order-OrderLines pair. But, an
OrderLine typically
has other business meaningful properties, maknig a stronger case for the
OrderLine class. In my
case, the only reason for ExtractionStudy is for a reference back to Extraction
for persistence
via a UOW. As it happens (rightly or wrongly), an Extraction has a list of
Compounds, Test
Substances, Method References and Analytes (defined in reference data).
Currently the
associations look much like the study association:

Extraction ----------> 0..* MethodReference
|
-----------------> 0..* TestSubstance
|
-----------------> 0..* Compound
etc...

Given this UOW problem, it seems I need to move to the following model (unless
there really is a
better way):

Extraction ----------> 0..* ExtractionMethodReference 0..* -------> 1
MethodReference
|
-----------------> 0..* ExtractionTestSubstance 0..* ---------> 1
TestSubstance
|
-----------------> 0..* ExtractionCompound 0..* --------------> 1 Compound
etc...

If the user adds a new Compound, the code may look like:


// First call:
ExtractionCompound eCompound = ExtractionCompound.Create(extraction,
sourceCompound);

// During instantiation of ExtractionCompound
GetUOW().RegisterNew(this);

// Next
GetUOW().Commit();

// UOW calls onto the ExtractionCompound mapper (or possibly the Extraction
mapper), and asks it
to Insert the new ExtractionCompound object. This can now be done because
ExtractionCompound
knows about the Extraction, so persistence can be done.

Thanks for the comments on this. I know it is a slight detraction of DDD, but
personally I am
trying to work towards something that keeps my domain cohesive and uncluttered,
yet works.

NickRobinson




AggregateRelationshipsAndUnitOfWork is mentioned on: ThreadView


VeryQuickWiki Version 2.6.3 - HTML Export