Qual è il modo corretto di applicare i comandi agli oggetti in profondità nella gerarchia del modello?
Dato il seguente modello:
public class Picture : AggregateRoot
{
private string title;
private List<Shape> shapes;
}
public class Shape
{
private ShapeType Type;
private Color color;
}
Possiamo definire un comando CreatePicture e un evento PictureCreated:
public class CreatePicture
{
Guid PictureId { get; set;}
string Title { get; set;}
}
public class PictureCreated
{
Guid PictureId { get; set;}
string Title { get; set;}
}
Una semplice implementazione del gestore comandi potrebbe essere simile a questa:
var Picture = new Picture(cmd.PictureId, cmd.Title); // Internally store a PictureCreated event
repo.Add(Picture);
repo.Save(); // PictureCreated published
Quindi possiamo definire un comando AddShape e un evento ShapeAdded:
public class AddShape
{
Guid PictureId { get; set;}
ShapeType Type { get; set;}
}
public class ShapeAdded
{
Guid PictureId { get; set; }
Guid ShapeId { get; set;}
ShapeType Type {get; set; }
}
Ancora una volta, il gestore di comando ha questo aspetto:
var picture = repo.Get<Picture>(cmd.PictureId);
picture.AddShape(cmd.ShapeId, cmd.Title);
repo.Save(); // ShapeAdded published
Ma ora definiamo un comando ChangeShapeColor e l'evento ShapeColorChanged:
public class ChangeShapeColor
{
Guid PictureId { get; set; }
Guid ShapeId { get; set;}
Color Color { get; set;}
}
public class ShapeColorChanged
{
Guid PictureId { get; set; }
Guid ShapeId { get; set;}
Color Color { get; set;}
}
Non sono sicuro di come dovrebbe essere implementato il gestore di comandi:
Opzione 1. Tutte le operazioni passano attraverso l'immagine:
var picture = repo.Get<Picture>(cmd.PictureId);
picture.ChangeShapeColor(cmd.ShapeId, cmd.Color);
repo.Save(); // ShapeColorChanged published
Opzione 2. Le operazioni passano attraverso la forma, che cerchiamo da Picture:
var picture = repo.Get<Picture>(cmd.PictureId);
var shape = Picture.GetShape(cmd.ShapeId);
shape.SetColor(cmd.Color);
repo.Save(); // ShapeColorChanged published
L'opzione 1 non sembra troppo male finché non iniziamo a costruire un grafico più complicato. per es.
Building --(1..n)--> Floor --(1..n)--> Room --(1..n)--> Desk --(1..n)--> Equipment
Sembra anche che la radice aggregata si sia trasformata in un "controllore" (mi dispiace se questa è la terminologia sbagliata) e non è più un oggetto di dominio attuale.
Qual è il modo corretto di gestirlo? Posso trovare solo esempi banali / semplici online in cui il modello è praticamente piatto.
Molte grazie in anticipo.