Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/masastack/MASA.Framework/llms.txt

Use this file to discover all available pages before exploring further.

This guide walks you through building your first MASA Framework microservice from scratch. You will set up a project with automatic route mapping via ServiceBase, an in-process EventBus, and EF Core data access — all wired together in a minimal Program.cs. The entire setup takes about five minutes.

Prerequisites

  • .NET 6 SDK or later installed
  • Basic familiarity with ASP.NET Core Minimal APIs
1
Install the MASA Template
2
The fastest way to start is with the official project template. Install it globally from NuGet:
3
dotnet new --install Masa.Template
4
Create Your Project
5
Scaffold a new service named MyService:
6
dotnet new masafx -o MyService
cd MyService
7
You can also create the project from Visual Studio by selecting the MASA Framework Project template in the New Project dialog. The template pre-configures EventBus, Minimal APIs, and a sample service class.
8
(Alternative) Manual Setup
9
If you prefer to add MASA Framework to an existing ASP.NET Core project, install the three core packages:
10
.NET CLI
dotnet add package Masa.Contrib.Dispatcher.Events
dotnet add package Masa.Contrib.Service.MinimalAPIs
dotnet add package Masa.Contrib.Data.EFCore.SqlServer
Package Manager Console
Install-Package Masa.Contrib.Dispatcher.Events
Install-Package Masa.Contrib.Service.MinimalAPIs
Install-Package Masa.Contrib.Data.EFCore.SqlServer
PackageReference (csproj)
<PackageReference Include="Masa.Contrib.Dispatcher.Events" />
<PackageReference Include="Masa.Contrib.Service.MinimalAPIs" />
<PackageReference Include="Masa.Contrib.Data.EFCore.SqlServer" />
11
PackagePurposeMasa.Contrib.Dispatcher.EventsIn-process EventBus with [EventHandler] attribute scanningMasa.Contrib.Service.MinimalAPIsConvention-based route auto-mapping via ServiceBaseMasa.Contrib.Data.EFCore.SqlServerEF Core integration for SQL Server
12
Configure Program.cs
13
Wire everything together in Program.cs. The key calls are services.AddEventBus(), builder.AddServices() (which discovers all ServiceBase subclasses), and app.MapMasaMinimalAPIs() (which maps their routes):
14
var builder = WebApplication.CreateBuilder(args);

// Register the in-process EventBus.
// AddEventBus() scans MasaApp.GetAssemblies() for [EventHandler] methods automatically.
builder.Services.AddEventBus();

// AddServices() scans all loaded assemblies for ServiceBase subclasses,
// registers them in DI, and returns the built WebApplication.
// This call must come last before app.Run().
var app = builder.AddServices();

// MapMasaMinimalAPIs() iterates every registered ServiceBase and calls
// AutoMapRoute(), translating method names to HTTP verbs and URL patterns.
app.MapMasaMinimalAPIs();

app.Run();
15
builder.AddServices() must be the last call on builder before app.Run(). Registering services after this call may not be reflected in the DI container.
16
Define a Service and an Event Handler
17
Service class — Inherit from ServiceBase and pass a base URI to the constructor. Public methods whose names start with a recognised HTTP verb prefix (Get, Post, Put, Delete) are mapped automatically. The Async suffix and the verb prefix are stripped from the route segment.
18
public class OrderService : ServiceBase
{
    // All routes will be prefixed with /api/v1/orders
    public OrderService() : base("/api/v1/orders") { }

    // Mapped to: GET /api/v1/orders
    public async Task<List<Order>> GetListAsync(
        [FromServices] IOrderRepository repo)
        => await repo.GetListAsync();

    // Mapped to: POST /api/v1/orders
    public async Task CreateAsync(
        [FromBody] CreateOrderCommand cmd,
        [FromServices] IEventBus eventBus)
        => await eventBus.PublishAsync(cmd);
}
19
ServiceBase exposes:
20
  • BaseUri — the route prefix set in the constructor.
  • App — the WebApplication instance, resolved via MasaApp.
  • Services — the global IServiceCollection.
  • GetRequiredService<T>() — convenience wrapper over the request IServiceProvider.
  • 21
    Event and handler — Declare a plain class that implements the command, then use [EventHandler] to mark the handling method. AddEventBus() discovers this class automatically through assembly scanning:
    22
    // The command event — inherits from the framework Event base
    public record CreateOrderCommand(string Name) : Event;
    
    // The handler class — no interface required, just [EventHandler]
    public class OrderCommandHandler
    {
        [EventHandler]
        public async Task HandleCreateAsync(
            CreateOrderCommand cmd,
            IOrderRepository repo)
            => await repo.AddAsync(new Order(cmd.Name));
    }
    
    23
    Handler method parameters are resolved from the DI container automatically (similar to Minimal API parameter binding), so you do not need to inject services through the constructor — just declare them as method parameters.

    Run the Service

    dotnet run
    
    Navigate to https://localhost:<port>/api/v1/orders to verify the GET endpoint is live. Use a tool like curl or Postman to test the POST endpoint:
    curl -X POST https://localhost:<port>/api/v1/orders \
      -H "Content-Type: application/json" \
      -d '{"name": "Widget"}'
    

    What Happens Under the Hood

    AddEventBus() calls MasaApp.GetAssemblies() to obtain the loaded assembly list, then uses DefaultDispatchNetworkProvider to reflect over every type and find methods decorated with [EventHandler]. Each handler type is registered in DI at ServiceLifetime.Scoped by default. When IEventBus.PublishAsync<TEvent>() is called, the framework resolves the correct handler chain and executes it in declaration order (controlled by the Order property on the attribute).
    builder.AddServices() delegates to ServiceCollectionExtensions.AddServices(), which scans MasaApp.GetAssemblies() for all concrete types that inherit ServiceBase. Each discovered type is registered as a singleton in the DI container and its Type is recorded in GlobalMinimalApiOptions.ServiceTypes for use by MapMasaMinimalAPIs().
    MapMasaMinimalAPIs() iterates GlobalMinimalApiOptions.ServiceTypes, resolves each ServiceBase instance from the DI container, and calls serviceInstance.AutoMapRoute(). That method reflects over the public instance methods declared directly on the class and calls App.MapMethods() (or App.MapGet/Post/Put/Delete) for each one, deriving the HTTP verb and URL segment from the method name prefix.

    Next Steps

    Architecture

    Understand the full BuildingBlocks/Contrib two-layer design and MasaApp internals.

    Event Bus

    Explore middleware pipelines, saga handlers, retry policies, and failure levels.

    Build docs developers (and LLMs) love