Ho un AR e non riesco a capire il modo migliore per creare / modificare alcuni complessi aggregati in esso contenuti. Questi aggregati hanno molti parametri quindi ho deciso all'interno del modello di dominio di utilizzare oggetti valore anziché tipi primitivi.
public class Load : AggregateRoot
{
public virtual string Name { get; protected set; }
public virtual User ResponsibilityOf { get; protected set; }
public virtual User AssignedTo { get; protected set; }
public virtual User CoveredBy { get; protected set; }
public virtual State State { get; protected set; }
public virtual Cargo Cargo { get; protected set; }
public virtual Guid CustomerId { get; protected set; }
public virtual IList<Run> Runs { get; protected set; }
public Load(Guid customerId, string name) : this()
{
if (string.IsNullOrEmpty(name))
throw new ArgumentNullException(nameof(name));
Name = name;
CustomerId = customerId;
Runs = new List<Run>();
}
}
Runs è una collezione di Value Objects e Run è definita di seguito. È un buon esempio del problema che sto affrontando perché richiede diversi parametri e alcuni di essi sono oggetti valore.
public sealed class Run : ValueObject<Run>
{
public int Order { get; private set; }
public Location Origin { get; private set; }
public Location Destination { get; private set; }
public Guid CarrierId { get; private set; }
private Run() { }
public Run(Guid carrierId, Location origin, Location destination, int order = 0) : this()
{
if (carrierId == Guid.Empty)
throw new ArgumentNullException(nameof(carrierId));
Origin = origin ?? throw new ArgumentNullException(nameof(origin));
Destination = destination ?? throw new ArgumentNullException(nameof(destination));
Order = order;
CarrierId = carrierId;
}
}
Voglio aggiungere metodi per le operazioni CRUD per le corse in AR (caricamento) e non so come affrontarlo. Questo sarebbe un compito banale se Origin e Destination erano primitivi o hanno solo preso uno o due parametri per creare un'istanza. Ma l'origine e la destinazione sono oggetti valore.
public sealed class Location: ValueObject<Location>
{
public string Name { get; private set; }
public Address Address { get;private set; }
public string Notes { get; private set; }
public string Directions { get; private set; }
public int CustomerId { get; private set; }
public string HoursOfOperation { get; private set; }
public Phone Phone { get; private set; }
}
Quindi quando vado ad aggiungere i miei metodi CRUD al carico principale di aggregazione, sono perso sul modo migliore per raggiungere questo obiettivo. Potrei aggiungere il seguente, ma non sembra il modo DDD per risolvere questo problema perché al di fuori del dominio non si dovrebbe sapere quale Run è giusto?
void AddRun(Run run);
void RemoveRun(Run run);
void UpdateRun(Guid id, Run run );
Se al di fuori del dominio non si conosce cosa sia Run, dovrei usare i tipi primitivi come parametri e questo diventerebbe molto veloce perché ci sarebbero molti parametri per costruire l'oggetto.
Modifica 1: Corretti alcuni aspetti indicati nelle risposte.