ConcordIO.AsyncApi.Client
0.8.7
dotnet add package ConcordIO.AsyncApi.Client --version 0.8.7
NuGet\Install-Package ConcordIO.AsyncApi.Client -Version 0.8.7
<PackageReference Include="ConcordIO.AsyncApi.Client" Version="0.8.7"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
<PackageVersion Include="ConcordIO.AsyncApi.Client" Version="0.8.7" />
<PackageReference Include="ConcordIO.AsyncApi.Client"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> </PackageReference>
paket add ConcordIO.AsyncApi.Client --version 0.8.7
#r "nuget: ConcordIO.AsyncApi.Client, 0.8.7"
#:package ConcordIO.AsyncApi.Client@0.8.7
#addin nuget:?package=ConcordIO.AsyncApi.Client&version=0.8.7
#tool nuget:?package=ConcordIO.AsyncApi.Client&version=0.8.7
ConcordIO.AsyncApi.Client
An MSBuild task package that generates C# contract types from AsyncAPI specifications at build time. Designed for consumers of MassTransit message contract packages — install the package and get strongly-typed message classes generated automatically on build.
This README is included as the NuGet package readme.
Installation
Add the package reference to your consumer project:
<ItemGroup>
<PackageReference Include="ConcordIO.AsyncApi.Client" Version="0.1.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
When combined with a contract package that defines ConcordIOAsyncApiContract items, C# types are generated automatically before compilation.
Runtime Compatibility
The MSBuild task assembly is packaged for net8.0, net9.0, and net10.0, and the .targets file selects the task based on the MSBuild runtime, not the consuming project's TFM.
- Consuming projects targeting .NET 8 and above can use this package regardless of their specific framework version.
- Supports all modern .NET SDK builds (.NET 8/9/10).
How It Works
- A contract package (produced by
ConcordIO.AsyncApi.Serverorconcordio generate) exposes AsyncAPI spec files asConcordIOAsyncApiContractMSBuild items. - This client package picks up those items and runs
GenerateContractsTaskbeforeCoreCompile. - The task generates C# source files in
obj/{Config}/{TFM}/ConcordIO.AsyncApi.Generated/and adds them to compilation.
Contract NuGet Package
└── asyncapi/MyService.Contracts.yaml
└── build/MyService.Contracts.targets ← defines <ConcordIOAsyncApiContract>
│
▼
ConcordIO.AsyncApi.Client (this package)
└── GenerateContractsTask
│ Reads AsyncAPI spec
│ Detects external types in referenced assemblies
│ Generates C# with proper namespaces
│
▼
obj/.../ConcordIO.AsyncApi.Generated/
├── MyService.Contracts.Events.g.cs
├── MyService.Contracts.Commands.g.cs
└── MyService.Contracts.Common.g.cs
Configuration
All properties are optional with sensible defaults.
| MSBuild Property | Default | Description |
|---|---|---|
ConcordIOClientOutputPath |
$(BaseIntermediateOutputPath)ConcordIO.AsyncApi.Generated\ |
Output directory for generated files. |
ConcordIOClientGenerateDataAnnotations |
true |
Generate [Required], [StringLength], etc. |
ConcordIOClientGenerateNullableReferenceTypes |
true |
Generate nullable reference type annotations (?). |
ConcordIOClientClassStyle |
Poco |
Class style: Poco or Record. |
Example: Override Settings
<PropertyGroup>
<ConcordIOClientClassStyle>Record</ConcordIOClientClassStyle>
<ConcordIOClientGenerateDataAnnotations>false</ConcordIOClientGenerateDataAnnotations>
</PropertyGroup>
Generated Output
Each namespace in the AsyncAPI document produces a separate .g.cs file:
// MyService.Contracts.Events.g.cs
// <auto-generated>
// This code was generated by ConcordIO.AsyncApi.Client.
// Do not modify this file directly.
// </auto-generated>
#nullable enable
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using MyService.Contracts.Common;
namespace MyService.Contracts.Events;
public partial class OrderCreatedEvent
{
public Guid OrderId { get; set; }
public DateTimeOffset Timestamp { get; set; }
public Customer Customer { get; set; }
}
External Type Detection
If a type defined in the AsyncAPI spec already exists in a referenced assembly, the generator will:
- Skip generating that type
- Add a
usingstatement for its namespace
This avoids duplicate type definitions when contract types are shared via a common library.
MSBuild Targets
| Target | When | Description |
|---|---|---|
ConcordIOGenerateContracts |
BeforeTargets="CoreCompile" |
Generates C# from ConcordIOAsyncApiContract items. |
ConcordIOCleanGeneratedContracts |
AfterTargets="Clean" |
Removes the generated output directory. |
Troubleshooting
Task instantiation error (MetadataLoadContext disposed)
Symptom:
The "ConcordIO.AsyncApi.Client.Tasks.GenerateContractsTask" task could not be instantiated...
Type must be a type provided by the runtime.
The "GenerateContractsTask" task generated invalid items...
MetadataLoadContext that created it has been disposed.
Cause: The task assembly was selected based on $(TargetFramework) rather than the MSBuild runtime, causing MSBuild to load the task in a metadata-only context.
Solution: Upgrade to a version that selects the task assembly by MSBuild runtime and includes a net9.0+ task build.
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.
MSBuild error parsing MSBuildRuntimeVersion
Symptom:
error MSB4184: The expression "[System.Version]::Parse('')" cannot be evaluated.
Cause: Some MSBuild hosts provide an empty $(MSBuildRuntimeVersion) during restore/build, which caused the task TFM selection logic to attempt parsing an empty version string.
Solution: Upgrade to a version that guards empty $(MSBuildRuntimeVersion) values and falls back to the net9.0 task build.
Generation doesn't run
Symptom: Build succeeds but no .g.cs files are generated.
Causes and solutions:
No contract items: Verify
@(ConcordIOAsyncApiContract)items exist:dotnet build -v n # Look for "ConcordIO.Client: AsyncAPI files:" in outputContract package not restored: Run
dotnet restorebefore buildingMissing package reference: Ensure both contract package and
ConcordIO.AsyncApi.Clientare referenced
Build errors in generated code
Symptom: Compilation errors in *.g.cs files.
Solutions:
Invalid AsyncAPI schema: Validate your AsyncAPI document
Namespace conflicts: Ensure
x-dotnet-namespacevalues don't conflict with existing typesMissing dependencies: Check that shared types are properly referenced
"Generating contracts from 2 AsyncAPI file(s)" with only one file on disk
Symptom: Build logs show duplicate AsyncAPI processing and repeated Generated ... from <file> lines.
Cause: Upstream package targets can re-emit ConcordIOAsyncApiContract items with Include, which duplicates the same file path in the MSBuild item list.
Current behavior:
- Client template metadata enrichment updates items in-place (
Update) instead of adding duplicates. - The
ConcordIO.AsyncApi.Clienttarget removes duplicate AsyncAPI items before invoking the task. - The task also deduplicates file paths as a defensive fallback.
Missing enum types from schema definitions
Symptom: Generated classes reference enum types (for example DhlRateSyncCancellationReason) that are not emitted.
Cause: Some contracts define enums only inside a parent schema's definitions block instead of as top-level components/schemas entries.
Current behavior: The generator extracts definition-scoped enum schemas and emits them as regular generated types in the same namespace, while still avoiding duplicate generation of shared object definitions.
External types not detected
Symptom: Types are regenerated instead of being referenced from existing assemblies.
Solutions:
Assembly not in references: Ensure the assembly with existing types is referenced
Type name mismatch: The
x-dotnet-typeextension must match the full type name exactlyBuild order: Ensure dependent projects build before the consuming project
Verbose logging
For detailed MSBuild logging:
dotnet build -v diag > build.log
# Search for "ConcordIO" in build.log
Advanced Usage
Custom Output Location
Generate files to a source-controlled directory:
<PropertyGroup>
<ConcordIOClientOutputPath>$(MSBuildProjectDirectory)\Generated\</ConcordIOClientOutputPath>
</PropertyGroup>
Conditional Generation
Skip generation in specific configurations:
<Target Name="ConcordIOGenerateContracts" Condition="'$(Configuration)' != 'Release'" />
Manual AsyncAPI Files
Specify AsyncAPI files directly (without contract packages):
<ItemGroup>
<ConcordIOAsyncApiContract Include="specs\api.yaml" />
</ItemGroup>
Related Projects
- ConcordIO.AsyncApi — Shared library with core generation logic
- ConcordIO.AsyncApi.Server — Server-side: generates the AsyncAPI spec from .NET types
- ConcordIO.Tool — CLI tool for contract package management
License
Licensed under the MIT License.
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 | 127 | 2/21/2026 |