Skip to main content
The Services Modeler provides a visual design surface for modeling your application’s service layer, including operations, commands, queries, and data transfer objects (DTOs). It supports CQRS patterns, RESTful API design, and service-oriented architecture.

Overview

The Services Modeler is based on the Intent.Modelers.Services module, which provides:
  • Visual modeling of service contracts and operations
  • Support for CQRS (Command Query Responsibility Segregation) patterns
  • DTO and service operation definitions
  • Query and command modeling
  • Pagination support
  • Integration with domain models

Designer Configuration

The Services designer is configured with:
  • Designer ID: 81104ae6-2bc5-4bae-b05a-f987b0372d81
  • Designer Name: Services
  • Order: 20 (appears after Domain in the designer list)
  • Type Systems: Common Types, Services Types

Core Elements

Service

Services represent logical groupings of related operations, typically corresponding to controllers or service classes. Properties:
  • Name: Service name (e.g., CustomerService, OrderManagement)
  • Operations: Collection of operations exposed by the service
  • Folder: Organizational folder/namespace
Example Usage:
var service = element.AsServiceModel();
var operations = service.Operations;
var serviceName = service.Name;

Command

Commands represent operations that change state (following CQRS principles). Properties:
  • Name: Command name (e.g., CreateOrder, UpdateCustomer)
  • Return Type: Optional return type (often void or an ID)
  • Parameters: Input parameters or a single DTO parameter
  • Fields: When using request objects, fields on the command DTO
Common Patterns:
  • Create operations: Return the created entity’s ID
  • Update operations: Often return void
  • Delete operations: Return void
Example Usage:
var command = element.AsCommandModel();
var returnType = command.TypeReference;
var parameters = command.Parameters;

Query

Queries represent operations that retrieve data without side effects (following CQRS principles). Properties:
  • Name: Query name (e.g., GetCustomerById, SearchProducts)
  • Return Type: The type of data returned
  • Parameters: Query parameters (filters, search criteria)
  • Pagination: Optional pagination support
Common Return Types:
  • Single DTO
  • Collection of DTOs
  • Paged result
Example Usage:
var query = element.AsQueryModel();
var returnDto = query.TypeReference.Element;
var hasPagination = query.HasStereotype("Paginated");

DTO (Data Transfer Object)

DTOs represent data structures transferred between service layers and clients. Properties:
  • Name: DTO name
  • Fields: Properties on the DTO
  • Mapping: Associations to domain entities for mapping
DTO Types:
  • Command DTOs: Input for commands
  • Query DTOs: Output from queries
  • Response DTOs: Structured responses
Example Usage:
var dto = element.AsDTOModel();
var fields = dto.Fields;
foreach (var field in fields)
{
    var fieldName = field.Name;
    var fieldType = field.TypeReference.Element.Name;
}

DTO Field

Fields represent properties on DTOs. Properties:
  • Name: Field name
  • Type: Data type (primitives, enums, other DTOs, domain entities)
  • Is Nullable: Whether the field can be null
  • Is Collection: Whether it’s a collection type

Folder

Folders organize service elements hierarchically, typically mapping to namespaces or API route segments.

CQRS Pattern Support

Commands

Commands modify application state and should:
  • Have clear, action-oriented names (verbs)
  • Accept input data via parameters or a command DTO
  • Return minimal data (ID, void, or success indicator)
  • Trigger domain logic and validation
Example Commands:
  • CreateCustomer
  • UpdateOrderStatus
  • DeleteProduct
  • ProcessPayment

Queries

Queries retrieve data and should:
  • Have descriptive names indicating what data is retrieved
  • Accept filter/search parameters
  • Return DTOs (never domain entities directly)
  • Be idempotent (no side effects)
Example Queries:
  • GetCustomerById
  • SearchProducts
  • GetOrderHistory
  • FindUsersByRole

Segregation Benefits

  • Scalability: Scale read and write operations independently
  • Performance: Optimize queries separately from commands
  • Clarity: Clear separation of intent in the API
  • Security: Apply different authorization rules to reads vs writes

Pagination Support

The Services Modeler includes built-in pagination support through the Intent.Modelers.Services.Pagination package.

Adding Pagination

  1. Create a query operation
  2. Add the Paginated stereotype
  3. Configure page size and offset parameters
Generated Result:
PagedResult<CustomerDTO> GetCustomers(int pageNo, int pageSize);

Metadata API

Accessing Service Models

using Intent.Modelers.Services.Api;

var servicesPackage = model.GetServicesPackageModel();
var services = servicesPackage.Services;

Working with Services

var service = element.AsServiceModel();

foreach (var operation in service.Operations)
{
    if (operation.IsCommandModel())
    {
        var command = operation.AsCommandModel();
        // Handle command
    }
    else if (operation.IsQueryModel())
    {
        var query = operation.AsQueryModel();
        // Handle query
    }
}

Working with DTOs

var dto = element.AsDTOModel();

foreach (var field in dto.Fields)
{
    var name = field.Name;
    var type = field.TypeReference.Element.Name;
    var isNullable = field.TypeReference.IsNullable;
    var isCollection = field.TypeReference.IsCollection;
}

Mapping to Domain Entities

if (dto.Mapping != null)
{
    var domainEntity = dto.Mapping.Element.AsClassModel();
    // Generate mapping code
}

Designer Settings

The Services Modeler provides application-level settings:

Naming Conventions

Property Naming Convention
  • Options: Manual, Pascal Case, Camel Case
  • Default: Manual
  • Controls automatic naming when creating/renaming DTO fields
Entity Naming Convention
  • Options: Pascal Case, Camel Case, Manual
  • Default: Manual
  • Controls automatic naming when creating/renaming DTOs
Operation Naming Convention
  • Options: Camel Case, Manual, Pascal Case
  • Default: Manual
  • Controls automatic naming when creating/renaming operations

Integration Capabilities

Domain Interactions

The Services Modeler can interact with the Domain Modeler:
  • Map DTOs to domain entities
  • Call domain operations from commands
  • Trigger domain events
  • Access repositories
Detection: The Intent.Modelers.Services.DomainInteractions package is auto-detected and installed when needed.

Event Interactions

Services can publish and subscribe to events:
  • Publish integration events from commands
  • Subscribe to events in event handlers
  • Model event-driven workflows
Detection: The Intent.Modelers.Services.EventInteractions package is auto-detected when eventing is used.

Pagination

Pagination support is automatically detected and installed: Package: Intent.Application.Dtos.Pagination Version: 4.0.13+

Common Modeling Scenarios

RESTful CRUD Service

  1. Create a Service (e.g., ProductService)
  2. Add Command operations:
    • CreateProduct - Returns Guid
    • UpdateProduct - Returns void
    • DeleteProduct - Returns void
  3. Add Query operations:
    • GetProductById - Returns ProductDTO
    • GetProducts - Returns List<ProductDTO>
  4. Create DTOs:
    • CreateProductDTO - Input for create
    • UpdateProductDTO - Input for update
    • ProductDTO - Output representation

Search with Pagination

  1. Create a Query: SearchCustomers
  2. Add parameters: searchTerm, pageNo, pageSize
  3. Add Paginated stereotype
  4. Set return type: CustomerDTO
  5. Result: Returns PagedResult<CustomerDTO>

Command with Complex Input

  1. Create a Command: PlaceOrder
  2. Create a command DTO: PlaceOrderCommand
  3. Add fields to the DTO:
    • CustomerId: Guid
    • Items: List<OrderItemDTO>
    • ShippingAddress: AddressDTO
  4. Set command parameter type to PlaceOrderCommand
  5. Return type: Guid (order ID)

Integration with Modules

The Services Modeler integrates with:
  • ASP.NET Core Templates: Generate controllers and endpoints
  • MediatR Templates: Generate CQRS command and query handlers
  • Application Layer Templates: Generate application service classes
  • Mapping Templates: Generate AutoMapper or Mapster configurations
  • Validation Templates: Generate FluentValidation validators
  • OpenAPI/Swagger: Generate API documentation

Best Practices

  1. Follow CQRS Principles: Separate commands from queries clearly
  2. Use DTOs: Never expose domain entities directly through services
  3. Name Intentionally: Use action verbs for commands, descriptive names for queries
  4. Organize by Feature: Group related operations in the same service
  5. Leverage Pagination: Add pagination to list queries early
  6. Version Appropriately: Use folders to organize API versions
  7. Document Operations: Add comments explaining business rules and validation
  8. Keep DTOs Focused: Create specific DTOs for different operations
  9. Map Carefully: Use explicit mapping stereotypes to link DTOs to domain entities

Example Service Model

A typical e-commerce service layer might include:
Services:
- CustomerService
  Commands:
    - CreateCustomer → Guid
    - UpdateCustomer → void
    - DeleteCustomer → void
  Queries:
    - GetCustomerById(id: Guid) → CustomerDTO
    - SearchCustomers(term: string) → List<CustomerDTO>

- OrderService
  Commands:
    - PlaceOrder(command: PlaceOrderDTO) → Guid
    - CancelOrder(orderId: Guid) → void
    - UpdateOrderStatus(command: UpdateOrderStatusDTO) → void
  Queries:
    - GetOrderById(id: Guid) → OrderDTO
    - GetCustomerOrders(customerId: Guid, pageNo: int, pageSize: int) → PagedResult<OrderDTO>

DTOs:
- CustomerDTO
- PlaceOrderDTO
- OrderDTO
- OrderItemDTO
- UpdateOrderStatusDTO

Build docs developers (and LLMs) love