samedi 31 décembre 2022

Is there a proper way to use a Repository class in a Domain Model class in Domain Driven Design?

I have class of Items. These items can have a parent and subitems, which can also have subitems and so on recursively in a tree structure. The price of the Items should be the sum of the prices of all descendant Items. The items at the bottom of the tree structure already have price assigned and are available through the repository.

The repository is used to access a database where the data is structured with columns (Id, Name, ParentId, ChildIds, Price), though I'd prefer not to use SQL to implement domain logic. That's why I'm looking to implement the calculation of the price in the Item class of my domain model, but to perform a recursive search to get all descendants of an item, the item object needs access to a repository Class instance.

The class currently looks like this:


public item(string id, string name, string parentId, List\<string\> childIds)
{
this.Id = id;
this.Name = name;
this.ParentId = parentID;
this.ChildIds = childIds;
}

public string Id { get; init; }
public string Name { get; init; }
public string ParentId { get; init; }
public List<string> ChildIds{ get; init; }
public int Price { get; init => CalculatePrice(this.Id) }

public int CalculatePrice(string id) {
list<Item> descendantItems = _itemsRepository.GetAllDescendants(id);

return descendantItems.Select(i => i.Price).Sum()

}

The only options I see to get access to my repository class both look pretty bad :

  • Pass an instance of the ItemsRepository class to the constructor of my Item class
  • Create a new instance of the ItemsRepository class in my CalculatePrice() method

An alternative I see is to have a field for the list of descendant items and fill it when my item is constructed but it seems like a waste to have all descendant items constructed and available in a field just because I need to assign a price to an item.

The final alternative I'm currently working on is to just get the Sum of the prices of all descendants by using a recursive SQL query in my mapper and to pass the resulting SumPrice to the constructor of the Item. This solves my problem, but it seems counter to Domain Driven Design to implement this business logic in an SQL Query in my Persistence layer.

Aucun commentaire:

Enregistrer un commentaire