Skip to main content
This quickstart guide will walk you through creating a complete ASP.NET Core Web API with Entity Framework Core and MediatR using Intent Architect. You’ll learn the fundamentals of model-driven development and see code generation in action.
Before starting, ensure you have installed Intent Architect and the .NET SDK (6.0 or later).

What We’ll Build

We’ll create a Product Catalog API with:
  • RESTful endpoints for managing products
  • CQRS pattern using MediatR
  • Entity Framework Core for data persistence
  • SQL Server database
  • Complete CRUD operations
This tutorial takes approximately 15 minutes to complete.

Create a New Solution

1

Launch Intent Architect

Open Intent Architect from your applications menu.
2

Create New Solution

  1. Click Create New Solution on the welcome screen
  2. Enter solution name: ProductCatalog
  3. Choose a location for your solution
  4. Click Create
3

Select Application Template

Intent Architect will prompt you to select an application template:
  1. Choose Clean Architecture with ASP.NET Core
  2. Configure the application:
    • Application Name: ProductCatalog
    • API Type: ASP.NET Core Web API
    • CQRS Pattern: MediatR
    • Database Provider: SQL Server
    • ORM: Entity Framework Core
  3. Click Create Application
The application template automatically installs and configures the necessary modules for your architecture.

Understand the Solution Structure

Intent Architect creates a solution with the following structure:
ProductCatalog/
├── ProductCatalog.sln                    # Intent Architect solution
├── ProductCatalog.Domain/                # Domain models and events
├── ProductCatalog.Application/           # Application layer (CQRS)
├── ProductCatalog.Infrastructure/        # Data access and external services
└── ProductCatalog.Api/                   # API controllers and startup
You’ll work primarily in the visual designers within Intent Architect. The C# projects will be generated automatically.

Model Your Domain

Let’s create a Product entity using the Domain Designer.
1

Open Domain Designer

  1. In Intent Architect, double-click Domain in the solution explorer
  2. This opens the Domain Designer canvas
2

Create Product Entity

  1. Right-click on the canvas
  2. Select New Class
  3. Name it Product
  4. Press Enter
3

Add Attributes

Right-click on the Product class and select Add Attribute for each property:
NameTypeRequired
Namestring
Descriptionstring
Pricedecimal
StockQuantityint
Skustring
IsActivebool
An Id property of type guid is automatically added to all entities.
4

Configure the Sku Attribute

Let’s add a database index to the Sku field:
  1. Right-click on the Sku attribute
  2. Select Apply StereotypeIndex
  3. In the stereotype properties:
    • Set Is Unique to true
This ensures SKUs are unique in the database.
5

Save the Model

Press Ctrl+S to save your domain model.
Your Product entity should look like this in the designer:
┌─────────────────────────┐
│       Product           │
├─────────────────────────┤
│ Id: guid                │
│ Name: string            │
│ Description: string     │
│ Price: decimal          │
│ StockQuantity: int      │
│ Sku: string [Index]     │
│ IsActive: bool          │
└─────────────────────────┘

Create Service Operations

Now let’s create the API operations using the Services Designer.
1

Open Services Designer

  1. In Intent Architect, double-click Services in the solution explorer
  2. This opens the Services Designer canvas
2

Create Products Service

  1. Right-click on the canvas
  2. Select New Service
  3. Name it Products
  4. Press Enter
3

Add CQRS Operations

Right-click on the Products service and add these operations:Commands (Create, Update, Delete):
  1. Create Command:
    • Right-click → Add OperationCreate
    • This creates a CreateProduct command
    • Map the parameters to your Product entity attributes
  2. Update Command:
    • Right-click → Add OperationUpdate
    • Creates UpdateProduct command
  3. Delete Command:
    • Right-click → Add OperationDelete
    • Creates DeleteProduct command
Queries (Read operations):
  1. Get By Id Query:
    • Right-click → Add OperationQuery
    • Name it GetProductById
    • Add parameter: id (guid)
    • Set return type: ProductDto
  2. Get All Query:
    • Right-click → Add OperationQuery
    • Name it GetProducts
    • Set return type: ProductDto[] (collection)
4

Configure DTOs

Intent Architect automatically creates DTOs (Data Transfer Objects) for your operations.
  1. Find the ProductDto in the Services Designer
  2. Verify it has all the fields from your Product entity
  3. If not, right-click on an operation and use Map from Domain to automatically create mappings
5

Save the Model

Press Ctrl+S to save your services model.

Install Additional Modules

Let’s ensure we have all necessary modules installed.
1

Open Module Manager

Press Ctrl+M or click the Module Manager button in the toolbar.
2

Verify Core Modules

Ensure these modules are installed (they should be from the template):
  • Intent.AspNetCore - ASP.NET Core hosting
  • Intent.AspNetCore.Controllers - Web API controllers
  • Intent.Application.MediatR - MediatR CQRS
  • Intent.EntityFrameworkCore - Entity Framework Core
  • Intent.EntityFrameworkCore.Repositories - Repository pattern
  • Intent.Entities - Domain entity generation
3

Install Swagger Module (Optional)

For API documentation, install the Swagger module:
  1. Search for Intent.AspNetCore.Swashbuckle
  2. Click Install
  3. Accept any dependency installations

Configure Module Settings

1

Open Application Settings

Right-click on your application in the solution explorer and select Settings.
2

Configure Entity Framework

  1. Navigate to EntityFrameworkCoreDatabase Settings
  2. Configure:
    • Database Provider: SQL Server
    • Table Naming Convention: Pluralized
  3. Click Save
3

Configure ASP.NET Core

  1. Navigate to ASP.NET Core Settings
  2. Configure:
    • Enable HTTPS Redirect: True
    • Default API Route Prefix: api/
  3. Click Save

Generate Code

Now for the exciting part - generating your application!
1

Run the Software Factory

Click the Run Software Factory button (or press F5).Intent Architect will:
  • Generate domain entities
  • Generate MediatR commands and queries
  • Generate command/query handlers
  • Generate API controllers
  • Generate Entity Framework DbContext
  • Generate repository implementations
  • Configure dependency injection
  • Set up the application startup
2

Review Changes

The Software Factory shows all files that will be created or modified.
  1. Review the changes (expand the tree to see specific files)
  2. Click Apply Changes
3

Open in IDE

Intent Architect will ask if you want to open the solution in your IDE.Click Yes to open in Visual Studio or your configured IDE.

Explore Generated Code

Let’s examine what Intent Architect generated:

Domain Entity

ProductCatalog.Domain/Entities/Product.cs
using System;
using Intent.RoslynWeaver.Attributes;

[assembly: DefaultIntentManaged(Mode.Fully)]
[assembly: IntentTemplate("Intent.Entities.DomainEntity", Version = "2.0")]

namespace ProductCatalog.Domain.Entities
{
    public class Product
    {
        public Guid Id { get; set; }
        
        public string Name { get; set; }
        
        public string Description { get; set; }
        
        public decimal Price { get; set; }
        
        public int StockQuantity { get; set; }
        
        public string Sku { get; set; }
        
        public bool IsActive { get; set; }
    }
}

MediatR Command

ProductCatalog.Application/Products/CreateProduct/CreateProductCommand.cs
using System;
using Intent.RoslynWeaver.Attributes;
using MediatR;

[assembly: DefaultIntentManaged(Mode.Fully)]
[assembly: IntentTemplate("Intent.Application.MediatR.CommandModels", Version = "1.0")]

namespace ProductCatalog.Application.Products.CreateProduct
{
    public class CreateProductCommand : IRequest<Guid>
    {
        public CreateProductCommand(
            string name,
            string description,
            decimal price,
            int stockQuantity,
            string sku,
            bool isActive)
        {
            Name = name;
            Description = description;
            Price = price;
            StockQuantity = stockQuantity;
            Sku = sku;
            IsActive = isActive;
        }

        public string Name { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }
        public int StockQuantity { get; set; }
        public string Sku { get; set; }
        public bool IsActive { get; set; }
    }
}

Command Handler

ProductCatalog.Application/Products/CreateProduct/CreateProductCommandHandler.cs
using System;
using System.Threading;
using System.Threading.Tasks;
using Intent.RoslynWeaver.Attributes;
using MediatR;
using ProductCatalog.Domain.Entities;
using ProductCatalog.Domain.Repositories;

[assembly: DefaultIntentManaged(Mode.Fully)]
[assembly: IntentTemplate("Intent.Application.MediatR.CommandHandler", Version = "2.0")]

namespace ProductCatalog.Application.Products.CreateProduct
{
    [IntentManaged(Mode.Merge, Signature = Mode.Fully)]
    public class CreateProductCommandHandler : IRequestHandler<CreateProductCommand, Guid>
    {
        private readonly IProductRepository _productRepository;

        public CreateProductCommandHandler(IProductRepository productRepository)
        {
            _productRepository = productRepository;
        }

        [IntentManaged(Mode.Fully, Body = Mode.Fully)]
        public async Task<Guid> Handle(CreateProductCommand request, CancellationToken cancellationToken)
        {
            var product = new Product
            {
                Name = request.Name,
                Description = request.Description,
                Price = request.Price,
                StockQuantity = request.StockQuantity,
                Sku = request.Sku,
                IsActive = request.IsActive
            };

            _productRepository.Add(product);
            await _productRepository.UnitOfWork.SaveChangesAsync(cancellationToken);
            
            return product.Id;
        }
    }
}

API Controller

ProductCatalog.Api/Controllers/ProductsController.cs
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Intent.RoslynWeaver.Attributes;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using ProductCatalog.Application.Products;
using ProductCatalog.Application.Products.CreateProduct;
using ProductCatalog.Application.Products.DeleteProduct;
using ProductCatalog.Application.Products.GetProductById;
using ProductCatalog.Application.Products.GetProducts;
using ProductCatalog.Application.Products.UpdateProduct;

[assembly: DefaultIntentManaged(Mode.Fully)]
[assembly: IntentTemplate("Intent.AspNetCore.Controllers.Controller", Version = "1.0")]

namespace ProductCatalog.Api.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ProductsController : ControllerBase
    {
        private readonly ISender _mediator;

        public ProductsController(ISender mediator)
        {
            _mediator = mediator;
        }

        [HttpPost]
        public async Task<ActionResult<Guid>> CreateProduct(
            [FromBody] CreateProductCommand command,
            CancellationToken cancellationToken = default)
        {
            var result = await _mediator.Send(command, cancellationToken);
            return Created($"api/products/{result}", result);
        }

        [HttpGet("{id}")]
        public async Task<ActionResult<ProductDto>> GetProductById(
            [FromRoute] Guid id,
            CancellationToken cancellationToken = default)
        {
            var result = await _mediator.Send(new GetProductByIdQuery(id: id), cancellationToken);
            return Ok(result);
        }

        [HttpGet]
        public async Task<ActionResult<List<ProductDto>>> GetProducts(CancellationToken cancellationToken = default)
        {
            var result = await _mediator.Send(new GetProductsQuery(), cancellationToken);
            return Ok(result);
        }

        [HttpPut("{id}")]
        public async Task<ActionResult> UpdateProduct(
            [FromRoute] Guid id,
            [FromBody] UpdateProductCommand command,
            CancellationToken cancellationToken = default)
        {
            if (id != command.Id)
            {
                return BadRequest();
            }

            await _mediator.Send(command, cancellationToken);
            return NoContent();
        }

        [HttpDelete("{id}")]
        public async Task<ActionResult> DeleteProduct(
            [FromRoute] Guid id,
            CancellationToken cancellationToken = default)
        {
            await _mediator.Send(new DeleteProductCommand(id: id), cancellationToken);
            return NoContent();
        }
    }
}
Notice the [IntentManaged] attributes. These tell Intent Architect which parts to fully manage and which parts you can customize.

Create Database Migration

Now let’s create the database schema.
1

Open Terminal

In your IDE, open a terminal in the solution directory.
2

Create Migration

Run the Entity Framework migration command:
dotnet ef migrations add InitialCreate --startup-project ProductCatalog.Api --project ProductCatalog.Infrastructure
This creates a migration file with your database schema.
3

Update Connection String

Open ProductCatalog.Api/appsettings.json and update the connection string:
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=ProductCatalog;Integrated Security=true;MultipleActiveResultSets=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information"
    }
  },
  "AllowedHosts": "*"
}
This connection string uses LocalDB. For SQL Server, use: Server=localhost;Database=ProductCatalog;Integrated Security=true;
4

Apply Migration

Apply the migration to create the database:
dotnet ef database update --startup-project ProductCatalog.Api --project ProductCatalog.Infrastructure
Your database is now created with the Products table!

Run the Application

1

Build the Solution

dotnet build
Ensure there are no compilation errors.
2

Run the Application

dotnet run --project ProductCatalog.Api
You should see output like:
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5000
3

Open Swagger UI

Navigate to https://localhost:5001/swagger in your browser.You’ll see your API documentation with all endpoints!

Test Your API

Let’s test the API using Swagger UI:
1

Create a Product

  1. In Swagger UI, expand the POST /api/Products endpoint
  2. Click Try it out
  3. Enter request body:
{
  "name": "Laptop",
  "description": "High-performance laptop for developers",
  "price": 1299.99,
  "stockQuantity": 50,
  "sku": "LAP-001",
  "isActive": true
}
  1. Click Execute
  2. You should get a 201 Created response with a GUID
2

Get All Products

  1. Expand the GET /api/Products endpoint
  2. Click Try it outExecute
  3. You should see your created product in the response
3

Get Product by ID

  1. Copy the ID from the previous response
  2. Expand the GET /api/Products/ endpoint
  3. Click Try it out
  4. Paste the ID
  5. Click Execute
  6. You should see the product details
4

Update Product

  1. Expand the PUT /api/Products/ endpoint
  2. Click Try it out
  3. Update the product details (e.g., change the price)
  4. Click Execute
  5. You should get a 204 No Content response
5

Delete Product

  1. Expand the DELETE /api/Products/ endpoint
  2. Click Try it out
  3. Enter the product ID
  4. Click Execute
  5. You should get a 204 No Content response
You can also use tools like Postman, curl, or the REST Client VS Code extension to test your API.

Make Changes and Regenerate

Let’s see Intent Architect’s power by adding a new field:
1

Add Category Field

  1. Switch back to Intent Architect
  2. Open the Domain Designer
  3. Right-click on ProductAdd Attribute
  4. Name: Category, Type: string, Required: ✓
  5. Save the model (Ctrl+S)
2

Regenerate Code

  1. Click Run Software Factory (F5)
  2. Review the changes - Intent Architect updates:
    • Product entity
    • DTOs
    • Commands
    • Database migrations
  3. Click Apply Changes
3

Create New Migration

dotnet ef migrations add AddCategoryToProduct --startup-project ProductCatalog.Api --project ProductCatalog.Infrastructure
dotnet ef database update --startup-project ProductCatalog.Api --project ProductCatalog.Infrastructure
4

Test the Changes

  1. Run the application again
  2. The Swagger UI now shows the Category field in requests/responses
  3. Create a product with a category and verify it works!
Notice how Intent Architect updated all related code automatically - entities, DTOs, commands, handlers, and controllers - maintaining consistency throughout your application.

What’s Next?

Add Validation

Add input validation using FluentValidation

Add Authentication

Secure your API with JWT authentication

Domain Events

Implement domain events for decoupled business logic

Explore Modules

Discover more modules to enhance your application

Key Takeaways

Model-Driven Development

You designed your application using visual models (Domain, Services) rather than writing boilerplate code.

Automated Code Generation

Intent Architect generated entities, commands, queries, handlers, controllers, repositories, and configuration automatically.

Pattern Consistency

All generated code follows CQRS, Clean Architecture, and repository patterns consistently.

Change Propagation

When you modified the model (added Category), changes propagated automatically throughout the codebase.

Production-Ready Code

The generated code includes dependency injection, async/await, proper HTTP status codes, and separation of concerns.

Troubleshooting

Software Factory Errors

If the Software Factory shows errors:
  1. Check that all required modules are installed
  2. Verify module versions are compatible
  3. Review module settings for configuration issues
  4. Check the Output window for detailed error messages

Database Connection Issues

# Test your connection string
dotnet ef dbcontext info --startup-project ProductCatalog.Api --project ProductCatalog.Infrastructure

# If using LocalDB, ensure it's installed
sqllocaldb info

Build Errors After Regeneration

  1. Clean and rebuild:
    dotnet clean
    dotnet build
    
  2. If issues persist, delete bin/ and obj/ folders:
    # PowerShell
    Get-ChildItem -Recurse -Directory -Filter bin | Remove-Item -Recurse -Force
    Get-ChildItem -Recurse -Directory -Filter obj | Remove-Item -Recurse -Force
    

Learn More

Congratulations!

You’ve successfully created your first Intent Architect application with:
  • ✓ Clean Architecture structure
  • ✓ CQRS with MediatR
  • ✓ Entity Framework Core
  • ✓ RESTful API with ASP.NET Core
  • ✓ Swagger documentation
  • ✓ Complete CRUD operations
You’re now ready to explore more advanced features and modules!

Build docs developers (and LLMs) love