Search code examples
c#domain-driven-designaggregaterootaggregates

How can I model a template-like entity in DDD?


I am a beginner with DDD and I try to model elegantly in C# the next scenario:

  1. A template that basically has only a name property on it and a list of items that have to be executed in a specific order.

    public class Template
    {
        public string Name { get; set; }
        public List<Item> Items { get; set; }
    }
    
    public class Item
    {
        public string Name { get; set; }
        public int Order { get; set; }
    }
    
  2. A type called Profile.

    public class Profile
    {
        public string Name { get; set; }
    }
    

The profile class is intended to say

  • I am using template A to know what items I have and in what order
  • If template A changes, then I am using the new version because I don't want to keep a clone of the list template A had.
  • If I am deleted then the template is not affected in any way
  • If I am created then I require a template
  • I can be looked after by my name only

This looks like the aggregate root would be the template, which would have a list of Items and a list of Profiles. But I feel that searching by the name of the profile is requiring me to search all the templates that have a profile with the given name. Somehow, coming from a CRUD background, it seems a high price to pay. Also, the profile is the one that uses the template and having the template know about profiles that use it, seems wrong.

How do you model this? What should be the aggregate root here? Is more than one? How do you perform the search if you want to use it from UI?


Solution

  • Neither Profile or Template can be nested within the other aggregate, they need to exist as separate aggregates. It sounds as though the Profile needs to keep a reference to which Template it is using. Therefore, I'd include a reference to the template by id (Template.Name).

    public class Template
    {
        public string Name { get; set; }
    
        public List<Item> Items { get; set; }
    }
    
    public class Item
    {
        public string Name { get; set; }
    
        public int Order { get; set; }
    }
    
    public class Profile
    {
        public string Name { get; set; }
    
        public string TemplateName { get; set; }
    }