Practicing DDD (Domain Driven Design) with Intent Architect
Intent Architect and our standard modules have extensive support for modelling DDD (Domain Driven Design) systems for both anemic and rich domain approaches.
A great introduction and explanation of these concepts is covered in our A Deep Dive into Domain Modeling Webinar.
Rich Domain Support in Intent Architect
Our designers have full support for Rich Domain modelling, in particular:
- You can model Operations (behaviors) on Domain Classes.
- In the Services designer Commands, Queries and Service Operations can be mapped directly to Class Operations.
Rich Domain Modelling Example
In this example we will enable "Private Setters" for our domain entities in our Application, model a Class with a Constructor and Operation in the Domain Designer and then in the Services Designer model CRUD Commands and Queries for interacting with our domain entity.
This example assumes you are using an already created Application or you've created a new Application with the "Clean Architecture .NET" application template:

Enabling "private setters"
In order to make it impossible to anemically update domain entities, you can enable the private setters option which makes all domain entities have private setters as opposed to the default of them being public.
Go to the Settings of the Application:

Under the Domain Settings section, enable Ensure Private Property Setters and press the Save Changes button.

Create a domain entity
In the Domain designer, create a Customer entity and add a Name attribute onto it:

Right-click the Customer and select the Add Constructor option:

Right-click the Constructor and select the Map Constructor... option:

Select the Name Attribute and then press the DONE button:

With the constructor created and mapped, you can run the Software Factory and observe the following happening in the Customer.cs file:

A public constructor has been created and because we mapped the Name, it has automatically created a parameter which sets the property.
Also note that a protected constructor has been created so that Entity Framework is still able to re-hydrate entities it reads from your database.
Similarly to creating the constructor, we will use the Add Operation context menu option:

We'll name it Update and then use the Map Operation... context menu option:

Again, just select the Name attribute and press DONE:

When running the Software Factory, observe that it adds a method to the Customer:

Create CQRS CRUD Operations
In the Services designer, right-click the Services Package and select the Create CQRS Operations option:

Observe that the CreateCustomerCommand is mapping to the constructor while the UpdateCustomerCommand is mapped to the Update operation:

To see the details of a mapping, we can right-click it and choose the appropriate menu option, for example for an [update] we can select the Map Entity Update option:

Observe how the Command is mapped to the Update Operation while the Name field is mapped to its parameter:

And when the Software Factory is run you will see that the generated implementation is passing the field's value to the method:

Conclusion
We have now created Rich Domain behaviors on our Domain entity and mapped our services to interact with them.
Advanced Example: Modeling Aggregates and Composite Entities
In certain scenarios, you may need to model an aggregate root (for example, an Order) that manages a collection of associated entities (for example, OrderLine). This section illustrates how to structure such a domain relationship in Intent Architect using private setters, map these structures through the Services designer, and expose operations to manage the aggregate.
Designing the Aggregate and Composite Entities
- Create the Domain Classes 
 In the Domain Designer, model a class named- Orderand another named- OrderLine. Establish a one-to-many relationship so that- Ordercontains a collection of- OrderLineentities.
  
- Use Private Setters and a Dedicated Constructor 
 To keep the domain model cohesive and prevent anemic updates, introduce a constructor that accepts a list or enumeration of- OrderLineDOdata objects. Within that constructor, create a collection to map these objects into actual- OrderLineentities:
public class Order
{
    private List<OrderLine> _orderLines = [];
    public Order(int refNo, IEnumerable<OrderLineDO> orderLines)
    {
        RefNo = refNo;
        _orderLines = orderLines.Select(s => new OrderLine(s.Description, s.Amount)).ToList();
    }
}

- Instantiate the Aggregate via a Command
 In the Services Designer, configure aCreateOrderCommandthat links to this constructor. Fields for critical properties, likeRefNoand the list ofOrderLineDO, can then be mapped automatically.
  
Managing Existing Aggregates
After the Order entity is created, you can add or modify OrderLine entities:
- Define a Domain Operation
 For instance, create anAddOrderLineoperation on theOrderentity. This method can accept parameters (e.g.,amount,description,quantity) and build a newOrderLine(this assumes yourOrderLinehas a constructor accepting:amount,description,quantity).
public void AddOrderLine(decimal amount, string description, int quantity)
{
    _orderLines.Add(new OrderLine(amount, description, quantity));
}

- Expose the Operation with a Command 
 Create an- AddOrderLineOrderCommand(or similar) in the Services Designer. Map its parameters to the- AddOrderLineoperation.
  
- Command Handler 
 Intent Architect will generate the handler logic, retrieving- Orderfrom the repository and invoking- AddOrderLine:
public async Task Handle(AddOrderLineOrderCommand request, CancellationToken cancellationToken)
{
    var order = await _orderRepository.FindByIdAsync(request.Id, cancellationToken);
    if (order is null)
    {
        throw new NotFoundException($"Could not find Order with Id '{request.Id}'");
    }
    order.AddOrderLine(request.Description, request.Amount);
}
This advanced example extends the concepts introduced earlier by demonstrating how to create aggregates with composite entities and expose domain operations through commands in Intent Architect—helping maintain a cohesive, rich domain model.