Dopo aver incontrato lo stesso problema, ecco la soluzione che ho implementato per questo.
Dominio
public class DomainObject : AggregateRootBase //implements IAggregateRoot
{
private ChildEntity _ChildEntity = null;
public ChildEntity ChildEntity
{
get
{
OnChildEntityRequested();
return _ChildEntity;
}
}
public event EventHandler ChildEntityRequested;
protected void OnChildEntityRequested()
{
if (ChildEntityRequested != null) { ChildEntityRequested(this, new EventArgs()); }
}
public static void SetChildEntity(DomainObject destination, ChildEntity child)
{
//To set or not to set, that is the question.
destination._ChildEntity = child;
}
}
Implementazione del repository
public class DomainObjectRepository : List<DomainObjectTracker>, IDomainObjectRepository
{
private void Load() //Method called by constructor or other loading mechanism.
{
foreach (DomainObjectDataModel dodm in ORMSystem) //Iterating through each object returned from ORM.
{
DomainObject do = Translate(dodm); //Translate into domain object.
do.ChildEntityRequested += new EventHandler(DomainObject_ChildEntityRequested);
DomainObjectTracker tracker = new DomainObjectTracker(do, dodm.Key);
base.Add(tracker);
}
}
protected void DomainObject_ChildEntityRequested(object sender, EventArgs e)
{
DomainObject source = sender as DomainObject;
//Here, you could check to see if it is null or stale before loading it.
//if (source.ChildEntity == null || IsStale(source.ChildEntity))
DomainObjectTracker tracker = base[IndexOf(source)];
ChildEntity entity = LoadChildEntity(tracker.Key); //Load the child entity from ORM.
DomainObject.SetChildEntity(source, entity);
}
}
Dopo aver esaminato la mia soluzione, potresti pensare: "Non sta chiamando un codice relativo all'infrastruttura degli eventi, ma sicuramente non si riferisce al mio dominio?". Anche se questo può essere vero, se ci pensi solo in termini di PI, allora ti rendi conto che stai solo offrendo un messaggio dal tuo dominio dicendo: "Ehi, sto per accedere a questa entità bambino". che consente al repository di rispondere con, "Aspetta, se ne hai bisogno uno (o uno nuovo), l'ho capito proprio qui nel mio db, quindi lascia che ti dica questo prima di continuare!".
Ci sono alcuni avvertimenti qui. Uno, significa che è necessario un evento per ogni entità figlio all'interno di un aggregato. Due, interrompe l'incapsulamento perché stai permettendo un modo pubblico di impostare l'entità figlio. Il rovescio della medaglia, i vantaggi sono il codice espressivo, le implementazioni dell'infrastruttura sono facilmente separate dal dominio, gli oggetti del dominio sono PI e l'ORM rimane incapsulato dietro l'implementazione del repository.
Se qualcuno ha un modo migliore di risolvere questo problema, sono tutto occhi!
Modifica
Inoltre, anche se la mia risposta fornisce una soluzione per PI, sono d'accordo con i commentatori di cui sopra. Hai bisogno di valutare se DDD è la risposta giusta per te perché, mentre rende un progetto più facile da mantenere e semplifica quello che altrimenti sarebbe un progetto molto complesso, ha un costo (solitamente tempo di sviluppo in anticipo e formazione del tuo team per organizzare correttamente il codice e utilizzare i vari modelli).