Skip to main content
The Intent.Entities module generates domain entities from your domain model, including properties, methods, constructors, and relationships.

Overview

This module creates:
  • Domain entity classes
  • Entity interfaces (optional)
  • Domain enums
  • Collection wrappers
  • Update helper methods
  • Exception classes (NotFoundException)

Installation

Intent.Entities

Key Features

Entity Generation

Entities are generated from your domain model with:
  • Properties with appropriate types and nullability
  • Constructors with parameters
  • Navigation properties for relationships
  • Methods for business logic
  • Support for inheritance
  • Generic type parameters
Example Entity
public class Customer
{
    public Customer(string name, string email)
    {
        Name = name;
        Email = email;
        Orders = new List<Order>();
    }

    protected Customer()
    {
        Orders = new List<Order>();
    }

    public Guid Id { get; private set; }
    public string Name { get; private set; }
    public string Email { get; private set; }
    public virtual ICollection<Order> Orders { get; private set; }

    public void UpdateName(string name)
    {
        Name = name;
    }

    public void UpdateEmail(string email)
    {
        Email = email;
    }

    public void AddOrder(Order order)
    {
        Orders.Add(order);
    }
}

Entity Interfaces

When Create Entity Interfaces is enabled, interfaces are generated:
Entity Interface
public interface ICustomer
{
    Guid Id { get; }
    string Name { get; }
    string Email { get; }
    ICollection<Order> Orders { get; }

    void UpdateName(string name);
    void UpdateEmail(string email);
    void AddOrder(Order order);
}

public class Customer : ICustomer
{
    // Implementation
}

Domain Enums

Domain Enum
public enum OrderStatus
{
    Pending = 0,
    Processing = 1,
    Completed = 2,
    Cancelled = 3
}

Value Objects

Supports value object generation:
Value Object
public class Address
{
    public Address(string street, string city, string zipCode)
    {
        Street = street;
        City = city;
        ZipCode = zipCode;
    }

    public string Street { get; private set; }
    public string City { get; private set; }
    public string ZipCode { get; private set; }

    public override bool Equals(object obj)
    {
        if (obj is not Address other) return false;
        return Street == other.Street && 
               City == other.City && 
               ZipCode == other.ZipCode;
    }

    public override int GetHashCode()
    {
        return HashCode.Combine(Street, City, ZipCode);
    }
}

Configuration Options

Generates separate partial classes for entity state and behavior.When enabled:
  • CustomerState.cs - Contains properties
  • Customer.cs - Contains methods and constructors
Benefits:
  • Cleaner code organization
  • Better separation of concerns
  • Easier code generation management
Default: false
Generates interfaces for all domain entities.Benefits:
  • Improved testability
  • Better abstraction
  • Support for dependency injection
Default: false
Makes all property setters private, enforcing encapsulation.Example:
public string Name { get; private set; }
Benefits:
  • Enforces invariants
  • Prevents external modification
  • Encourages method-based updates
Default: true
Uses implicit Intent tag mode for entity files.Reduces the need for explicit [IntentManaged] attributes.Default: true

Entity Relationships

One-to-Many

One-to-Many
public class Customer
{
    public virtual ICollection<Order> Orders { get; private set; }
}

public class Order
{
    public Guid CustomerId { get; private set; }
    public virtual Customer Customer { get; private set; }
}

Many-to-Many

Many-to-Many
public class Product
{
    public virtual ICollection<Category> Categories { get; private set; }
}

public class Category
{
    public virtual ICollection<Product> Products { get; private set; }
}

One-to-One

One-to-One
public class User
{
    public virtual UserProfile Profile { get; private set; }
}

public class UserProfile
{
    public Guid UserId { get; private set; }
    public virtual User User { get; private set; }
}

Inheritance

Supports entity inheritance:
Inheritance
public abstract class Person
{
    public Guid Id { get; protected set; }
    public string Name { get; protected set; }
    public string Email { get; protected set; }
}

public class Customer : Person
{
    public decimal CreditLimit { get; private set; }
    public virtual ICollection<Order> Orders { get; private set; }
}

public class Employee : Person
{
    public string EmployeeNumber { get; private set; }
    public string Department { get; private set; }
}

Constructors

Multiple constructor patterns:

Parameterized Constructor

Parameterized
public class Customer
{
    public Customer(string name, string email, decimal creditLimit)
    {
        Name = name;
        Email = email;
        CreditLimit = creditLimit;
        Orders = new List<Order>();
    }
}

Protected Parameterless Constructor

Protected Constructor
public class Customer
{
    protected Customer()
    {
        Orders = new List<Order>();
    }
}
Useful for:
  • EF Core materialization
  • Serialization
  • Testing frameworks

Methods

Update Methods

Update Methods
public void UpdateCustomerInfo(string name, string email)
{
    Name = name;
    Email = email;
}

public void IncreaseCreditLimit(decimal amount)
{
    if (amount <= 0)
        throw new ArgumentException("Amount must be positive", nameof(amount));
    
    CreditLimit += amount;
}

Business Logic

Business Logic
public bool CanPlaceOrder(decimal orderTotal)
{
    var currentCreditUsed = Orders
        .Where(o => o.Status != OrderStatus.Completed)
        .Sum(o => o.Total);
    
    return (currentCreditUsed + orderTotal) <= CreditLimit;
}

public void PlaceOrder(Order order)
{
    if (!CanPlaceOrder(order.Total))
        throw new InvalidOperationException("Credit limit exceeded");
    
    Orders.Add(order);
}

Exceptions

The module generates a NotFoundException for missing entities:
NotFoundException
public class NotFoundException : Exception
{
    public NotFoundException(string message) : base(message)
    {
    }

    public NotFoundException(string message, Exception innerException) 
        : base(message, innerException)
    {
    }

    public NotFoundException(string name, object key)
        : base($"Entity \"{name}\" ({key}) was not found.")
    {
    }
}
Usage:
Usage
public async Task<Customer> GetCustomerAsync(Guid id)
{
    var customer = await _repository.FindByIdAsync(id);
    
    if (customer == null)
        throw new NotFoundException(nameof(Customer), id);
    
    return customer;
}

Collection Helpers

Generated collection extension methods:
Collection Extensions
public static class CollectionExtensions
{
    public static void AddRange<T>(this ICollection<T> collection, IEnumerable<T> items)
    {
        foreach (var item in items)
        {
            collection.Add(item);
        }
    }

    public static void RemoveRange<T>(this ICollection<T> collection, IEnumerable<T> items)
    {
        foreach (var item in items)
        {
            collection.Remove(item);
        }
    }
}

Code-to-Model Synchronization

The module supports synchronizing code changes back to the domain model:
  • Add methods in code → Appear in domain model
  • Rename properties → Updates domain model
  • Add attributes → Creates in domain model
  • Delete elements → Removes from domain model
Enable Code-to-Model synchronization in the domain designer settings.

Best Practices

Encapsulation

Use private setters and public methods to enforce business rules and invariants.

Rich Domain Model

Add business logic methods directly to entities rather than in services.

Immutability

Consider making value objects immutable for better predictability.

Constructor Validation

Validate parameters in constructors to ensure entities are always in valid states.

Additional Resources

Build docs developers (and LLMs) love