ConcordIO.AsyncApi.Server 0.8.7

dotnet add package ConcordIO.AsyncApi.Server --version 0.8.7
                    
NuGet\Install-Package ConcordIO.AsyncApi.Server -Version 0.8.7
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ConcordIO.AsyncApi.Server" Version="0.8.7">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ConcordIO.AsyncApi.Server" Version="0.8.7" />
                    
Directory.Packages.props
<PackageReference Include="ConcordIO.AsyncApi.Server">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ConcordIO.AsyncApi.Server --version 0.8.7
                    
#r "nuget: ConcordIO.AsyncApi.Server, 0.8.7"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ConcordIO.AsyncApi.Server@0.8.7
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ConcordIO.AsyncApi.Server&version=0.8.7
                    
Install as a Cake Addin
#tool nuget:?package=ConcordIO.AsyncApi.Server&version=0.8.7
                    
Install as a Cake Tool

ConcordIO.AsyncApi.Server

An MSBuild task package that generates AsyncAPI 3.x specifications from .NET MassTransit message contracts at build time. Install it in a project that defines message types, and an AsyncAPI document is generated automatically on every build.

This README is included as the NuGet package readme.

Installation

Add the package reference to your contracts project:

<ItemGroup>
  <PackageReference Include="ConcordIO.AsyncApi.Server" Version="0.1.0">
    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    <PrivateAssets>all</PrivateAssets>
  </PackageReference>
</ItemGroup>

Configuration

Specifying Message Types

Define event and command types using MSBuild properties with semicolon-separated patterns:

<PropertyGroup>
  
  <ConcordIOEventTypes>MyService.Contracts.Events.*</ConcordIOEventTypes>

  
  <ConcordIOCommandTypes>MyService.Contracts.Commands.*</ConcordIOCommandTypes>
</PropertyGroup>

Type Discovery Patterns

Pattern Description Example
Namespace.* All public non-abstract types in exact namespace MyApp.Events.*
Namespace.** All types in namespace and sub-namespaces MyApp.Events.**
IMyInterface All implementations of the interface MyApp.IOrderEvent
MyBaseClass All subclasses of the base class MyApp.OrderEventBase
MyConcreteType A specific type MyApp.Events.OrderCreatedEvent

Properties

MSBuild Property Default Description
ConcordIOAsyncApiDocumentVersion $(Version) or 1.0.0 Version in the AsyncAPI document info block.
ConcordIOAsyncApiDocumentTitle $(AssemblyName) Title in the AsyncAPI document info block.
ConcordIOAsyncApiOutputFormat json Output format: json (default, more reliable) or yaml.
ConcordIOAsyncApiOutputPath $(IntermediateOutputPath)asyncapi\ Output directory for the generated spec.
ConcordIOIncludeAsyncApiInPackage true Include the spec in the NuGet package under asyncapi/.
ConcordIOEventTypes Semicolon-separated event type patterns.
ConcordIOCommandTypes Semicolon-separated command type patterns.

Example Configuration

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <ConcordIOEventTypes>MyService.Contracts.Events.*</ConcordIOEventTypes>
    <ConcordIOCommandTypes>MyService.Contracts.Commands.*</ConcordIOCommandTypes>
    <ConcordIOAsyncApiDocumentVersion>2.0.0</ConcordIOAsyncApiDocumentVersion>
    <ConcordIOAsyncApiOutputFormat>json</ConcordIOAsyncApiOutputFormat>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="ConcordIO.AsyncApi.Server" Version="0.1.0">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
  </ItemGroup>
</Project>

Generated Output

The generated AsyncAPI document is a contract catalog — it describes message schemas, namespaces, and types, but does not contain actual broker configuration (queue names, exchange bindings, server connections, consumer groups, etc.). Channel addresses use MassTransit's internal URN format (urn:message:{namespace}:{type}), not real broker endpoints.

This is by design: the contracts project defines message shapes, not hosting topology. Broker-specific details are determined at runtime by MassTransit based on consumer configuration and endpoint naming conventions.

The document follows the AsyncAPI 3.x specification with MassTransit-compatible URN addressing:

asyncapi: 3.0.0
info:
  title: MyService.Contracts
  version: 2.0.0
  description: Generated by ConcordIO.AsyncApi.Server

channels:
  MyService.Contracts.Events.OrderCreatedEvent:
    address: "urn:message:MyService.Contracts.Events:OrderCreatedEvent"
    messages:
      OrderCreatedEvent:
        $ref: '#/components/messages/OrderCreatedEvent'

components:
  messages:
    OrderCreatedEvent:
      name: OrderCreatedEvent
      title: OrderCreatedEvent
      contentType: application/json
      payload:
        $ref: '#/components/schemas/OrderCreatedEvent'

  schemas:
    OrderCreatedEvent:
      type: object
      x-dotnet-namespace: MyService.Contracts.Events
      x-dotnet-type: MyService.Contracts.Events.OrderCreatedEvent
      properties:
        orderId:
          type: string
          format: uuid
        timestamp:
          type: string
          format: date-time

NuGet Package Integration

When ConcordIOIncludeAsyncApiInPackage is true (default), the generated spec is automatically included in the NuGet package:

MyService.Contracts.nupkg
├── asyncapi/
│   └── MyService.Contracts.yaml
└── build/
    └── MyService.Contracts.targets    # Exposes ConcordIOAsyncApiContract items

The auto-generated .targets file exposes the spec as a ConcordIOAsyncApiContract MSBuild item so that consumers using ConcordIO.AsyncApi.Client can automatically generate C# types.

MSBuild Targets

Target When Description
ConcordIOGenerateAsyncApi AfterTargets="Build" Generates the AsyncAPI spec from discovered types.
ConcordIOIncludeAsyncApiInPackage BeforeTargets="GenerateNuspec" Includes the spec in the NuGet package.
ConcordIOGenerateContractTargets AfterTargets="ConcordIOGenerateAsyncApi" Auto-generates consumer .targets file.

Troubleshooting

MSBuild warning about task runtime/architecture

Symptom: Build shows a warning about the task falling back to out-of-process execution, sometimes followed by an MSBuild unhandled exception.

Cause: Older package versions did not specify explicit task runtime/architecture hints.

Solution: Upgrade to a version that includes explicit runtime/architecture hints in the MSBuild task registration.

YAML serialization errors

Symptom: Build fails with YamlDotNet.Core.SyntaxErrorException: Expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, got MappingEnd.

Cause: The YAML serializer encounters empty JsonObject nodes in the AsyncAPI document model (e.g., schemas with no properties).

Solution: Use JSON output format instead (this is now the default):

<PropertyGroup>
  <ConcordIOAsyncApiOutputFormat>json</ConcordIOAsyncApiOutputFormat>
</PropertyGroup>

JSON is more reliable for programmatic consumption and is treated as equivalent to YAML in the AsyncAPI 3.0 specification.

Custom output path ignored

Symptom: Setting ConcordIOAsyncApiOutputPath to a custom directory (e.g., $(MSBuildProjectDirectory)\asyncapi\) is ignored, and the spec is still written to obj/.

Cause: Fixed in v0.2.3+. Earlier versions required the path to contain obj.

Solution: Upgrade to v0.2.3 or later, or use a workaround with a post-build copy target:

<Target Name="CopyAsyncApiToStableLocation" AfterTargets="ConcordIOGenerateAsyncApi">
  <Copy SourceFiles="@(ConcordIOGeneratedAsyncApi)"
        DestinationFolder="$(MSBuildProjectDirectory)\asyncapi"
        SkipUnchangedFiles="true" />
</Target>

No types discovered

Symptom: Generated AsyncAPI document contains no channels or schemas.

Causes and solutions:

  1. Type patterns don't match: Check your ConcordIOAsyncApiTypePatterns values:

    dotnet build -v d  # Look for "ConcordIO.Server: Discovered channels:" in output
    
  2. Types not public: Only public types are discovered. Ensure your contract classes are public.

  3. Missing message markers: Types must have public properties and follow contract patterns.

Missing channel addresses

Symptom: Channels have empty or default addresses.

Solution: Specify URN addresses following MassTransit conventions:

urn:message:{Namespace}:{TypeName}

For example: urn:message:MyApp.Contracts:OrderSubmittedEvent

Namespace not applied

Symptom: Generated schemas don't have x-dotnet-namespace.

Solution: Set the property before build:

<PropertyGroup>
  <ConcordIOAsyncApiNamespace>MyCompany.Contracts</ConcordIOAsyncApiNamespace>
</PropertyGroup>

Consumer targets not working

Symptom: Projects referencing the contract package don't see ConcordIOAsyncApiContract items.

Causes:

  1. Package not packed: Run dotnet pack on the producer project

  2. Missing buildTransitive folder: The consumer targets file must be in buildTransitive/

  3. NuGet cache: Clear the NuGet cache: dotnet nuget locals all --clear

Verbose logging

For detailed MSBuild logging:

dotnet build -v diag > build.log
# Search for "ConcordIO.Server" in build.log

Advanced Usage

Custom Channel Address Format

Channel addresses follow MassTransit URN conventions: urn:message:{Namespace}:{TypeName}

Multi-Project Setup

For solutions with separate contracts and producer projects:

MyApp/
├── MyApp.Contracts/        # Shared type definitions
├── MyApp.Producer/         # References Contracts, generates AsyncAPI
│   └── MyApp.Producer.csproj
│       <PackageReference Include="ConcordIO.AsyncApi.Server" />
└── MyApp.Consumer/         # References generated contract package

Conditional Generation

Generate only in specific configurations:

<PropertyGroup Condition="'$(Configuration)' == 'Release'">
  <GenerateAsyncApiDocument>true</GenerateAsyncApiDocument>
</PropertyGroup>

License

Licensed under the MIT License.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.8.7 129 2/21/2026