Aid.Microservice.Server 2.3.0

dotnet add package Aid.Microservice.Server --version 2.3.0
                    
NuGet\Install-Package Aid.Microservice.Server -Version 2.3.0
                    
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="Aid.Microservice.Server" Version="2.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Aid.Microservice.Server" Version="2.3.0" />
                    
Directory.Packages.props
<PackageReference Include="Aid.Microservice.Server" />
                    
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 Aid.Microservice.Server --version 2.3.0
                    
#r "nuget: Aid.Microservice.Server, 2.3.0"
                    
#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 Aid.Microservice.Server@2.3.0
                    
#: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=Aid.Microservice.Server&version=2.3.0
                    
Install as a Cake Addin
#tool nuget:?package=Aid.Microservice.Server&version=2.3.0
                    
Install as a Cake Tool

Aid.Microservice.Server

A .NET library for building RPC microservices over RabbitMQ with support for multiple protocols and per-method serializers.

Quick Start

using Aid.Microservice.Server;
using Aid.Microservice.Server.Extensions;

var builder = MicroserviceHostBuilder.CreateBuilder(args);

builder.ConfigureServices((_, services) =>
{
    services.AddAidMicroservice(typeof(Program).Assembly);
});

var app = builder.Build();

app.Run();

Add appsettings.json with RabbitMQ connection:

{
    "RabbitMqConfiguration": {
        "Hostname": "localhost",
        "Port": 5672,
        "Username": "guest",
        "Password": "guest"
    }
}

Features

Declarative API

Mark classes and methods with [Microservice] and [RpcCallable]:

[Microservice]
public class SimpleService
{
    [RpcCallable]
    public int Multiple(int a, int b) => a * b;
}

Service name is inferred from the class name (SimpleServicesimple). Method name is inferred from the method name.

Custom Naming

Use aliases for cross-language compatibility:

[Microservice("just_name_me")]
public class NamedService
{
    [RpcCallable("and_me")]
    public int Subtract(int a, int b) => a - b;
}

Dependency Injection

Services are registered as Scoped. Inject any registered dependency:

[Microservice]
public class DiService(ILogger<DiService> logger)
{
    [RpcCallable]
    public void Log()
    {
        logger.LogInformation("DiService called");
    }
}

Async Methods

Full async/await support:

[Microservice]
public class AsyncService
{
    [RpcCallable]
    public async Task Delay(int seconds)
    {
        await Task.Delay(TimeSpan.FromSeconds(seconds));
    }
}

Proxy Support

Call other services from within a service using IRpcProxyFactory:

[Microservice]
public class ProxyService(IRpcProxyFactory factory)
{
    private readonly IRpcProxy _multipleProxy = factory.CreateProxy("simple");

    [RpcCallable]
    public async Task<string> MultiplyString()
    {
        var result = await _multipleProxy.CallAsync<int>("multiple", new { a = 5, b = 6 });
        return $"5 * 6 = {result}";
    }
}

Per-Service Serializers

Assign a custom serializer to an entire service:

[Microservice("python_bridge", SerializerType = typeof(NamekoSerializer))]
public class PythonBridge
{
    [RpcCallable]
    public int Add(int a, int b) => a + b;
}

All methods in this service will use NamekoSerializer and listen on the nameko-rpc exchange (inferred from the serializer's ExchangeName).

Per-Method Serializers

Mix different serializers within a single service:

[Microservice("mixed_service")]
public class MixedService
{
    [RpcCallable("nameko_add", SerializerType = typeof(NamekoSerializer))]
    public int NamekoAdd(int a, int b) => a + b;

    [RpcCallable]
    public int DefaultAdd(int a, int b) => a + b;
}

The server automatically detects all unique exchanges used by the service and creates a queue on each one.

Priority: [RpcCallable(SerializerType)] > [Microservice(SerializerType)] > protocol's DefaultSerializer.

Explicit Exchange Names

Control which exchange a service listens on:

// Single exchange for all methods
[Microservice("custom", ExchangeName = "my_custom_rpc")]
public class CustomExchangeService { ... }

// Multiple exchanges for different methods
[Microservice("multi", Exchanges = ["aid_rpc", "nameko-rpc"])]
public class MultiExchangeService { ... }

Global Exchange Override

Set ExchangeName in RabbitMqConfiguration to force all services onto a single exchange:

{
    "RabbitMqConfiguration": {
        "Hostname": "localhost",
        "ExchangeName": "all_in_one"
    }
}

Protocols & Serializers

Architecture

The library separates messaging protocol from message serialization:

Layer Interface Responsibility
Protocol IRpcProtocol Exchange type, exchange name, routing, binding
Serializer IRequestSerializer Body format (JSON structure, args/kwargs)

Built-in Protocols

Protocol Exchange Type Exchange Name Serializer
DefaultJsonProtocol Topic aid_rpc DefaultJsonSerializer
NamekoProtocol Topic nameko-rpc NamekoSerializer

Replacing the Default Protocol

using Aid.Microservice.Server.Extensions;
using Aid.Microservice.Shared.Protocols;

var builder = MicroserviceHostBuilder.CreateBuilder(args);

builder.ConfigureServices((context, services) =>
{
    // Replace default protocol (order does not matter)
    services.AddAidMicroserviceProtocol<NamekoProtocol>();

    services.AddAidMicroservice(typeof(Program).Assembly);
});

Custom Serializer

Implement IRequestSerializer for your own message format:

public class MySerializer : IRequestSerializer
{
    public string ContentType => "application/json";
    public string? ExchangeName => "my_exchange";

    public byte[] CreateRequest(string serviceName, string methodName, object? parameters, JsonSerializerOptions options)
    {
        // Build your message format
    }

    public RpcRequest ParseRequest(ReadOnlySpan<byte> body, string routingKey, JsonSerializerOptions options)
    {
        // Parse incoming message
    }

    public byte[] CreateResponse(RpcResponse response, JsonSerializerOptions options) { ... }
    public RpcResponse ParseResponse(ReadOnlySpan<byte> body, JsonSerializerOptions options) { ... }
}

Register and use it:

[Microservice("my_service", SerializerType = typeof(MySerializer))]
public class MyService { ... }

Configuration

RabbitMQ

{
    "RabbitMqConfiguration": {
        "Hostname": "localhost",
        "Port": 5672,
        "Username": "guest",
        "Password": "guest",
        "ExchangeName": "",
        "RetryCount": 3,
        "RecoveryInterval": 5
    }
}
Option Default Description
ExchangeName (per-protocol) Global override for all exchanges. Leave empty to use per-protocol defaults.
RetryCount 3 Connection retry attempts.
RecoveryInterval 5 Seconds between retries.
DeleteExchangesOnShutdown false Whether to delete declared exchanges when the server shuts down. Useful for development/cleanup.

Architecture Overview

RpcListenerHost
    │
    ├── For each (service, exchange) pair:
    │       ├── Declare exchange (deduplicated)
    │       ├── Declare queue: {exchange}_{service}
    │       └── Bind queue: service_name.*
    │
    └── On message received:
            ├── ResolveSerializer(serviceName, routingKey)
            │       ├── [RpcCallable(SerializerType)] → resolve
            │       ├── [Microservice(SerializerType)] → resolve
            │       └── fallback → protocol.DefaultSerializer
            ├── serializer.ParseRequest() → RpcRequest
            ├── RpcRequestDispatcher.DispatchAsync() → execute method
            └── serializer.CreateResponse() → send reply
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
2.3.0 102 4/11/2026
2.2.0 101 4/10/2026
2.1.0 119 12/28/2025
2.0.0 119 12/28/2025
1.0.1 281 7/20/2025
1.0.0 121 7/19/2025