FxMap 4.1.1

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

<p align="center"> <img src="https://raw.githubusercontent.com/quyvu01/FxMap/main/FxMap.png" alt="FxMap" width="120" /> </p>

<h1 align="center">FxMap</h1>

<p align="center"> Distributed data mapping for .NET — declare where a property comes from, and FxMap fetches it from the service that owns the data, over the transport you already run. </p>

<p align="center"> <a href="https://www.nuget.org/packages/FxMap"><img alt="NuGet" src="https://img.shields.io/nuget/v/FxMap.svg" /></a> <a href="https://www.nuget.org/packages/FxMap"><img alt="Downloads" src="https://img.shields.io/nuget/dt/FxMap.svg" /></a> <a href="https://github.com/quyvu01/FxMap/actions/workflows/build.yml"><img alt="Build" src="https://github.com/quyvu01/FxMap/actions/workflows/build.yml/badge.svg" /></a> <a href="LICENSE"><img alt="License" src="https://img.shields.io/badge/license-Apache--2.0-blue.svg" /></a> <img alt=".NET" src="https://img.shields.io/badge/.NET-8%20%7C%209%20%7C%2010-512BD4.svg" /> </p>

<p align="center"> <a href="https://fxmapper.net"><b>Documentation</b></a> · <a href="https://fxmapper.net/docs/quick-start/"><b>Getting Started</b></a> · <a href="https://fxmapper.net/docs/expressions"><b>Expression Language</b></a> · <a href="https://discord.gg/XJNzPbqg7"><b>Discord</b></a> </p>


In a microservice system a response often carries only keys: an order has a UserId, a ProvinceId, a ProductId. Showing it means collecting UserName, ProvinceName, ProductName from the services that own them, and writing that glue again for every endpoint. FxMap turns the glue into a declaration:

public class OrderResponse
{
    public string UserId { get; set; }
    public string UserName { get; set; }     // filled by FxMap
    public string UserEmail { get; set; }    // filled by FxMap
}

public class OrderResponseProfile : ProfileOf<OrderResponse>
{
    protected override void Configure() =>
        UseDistributedKey<UserDistributedKey>()
            .Of(x => x.UserId)
            .For(x => x.UserName)
            .For(x => x.UserEmail, "Email");
}

await distributedMapper.MapDataAsync(response);   // one batched request per key, however many objects

The service that owns the data registers an entity configuration and a data provider. FxMap batches the ids, sends them over a transport (or answers locally when the owner is the same service), and writes the results back. No client code per field, and no coupling between the two services beyond a key name.

Features

  • FluentAPI mapping: declare the mapping with ProfileOf<T> and EntityConfigureOf<T>; no attributes on your DTOs, and property access is compiled once per type.
  • Expression language: a SQL-like DSL for navigation, filters, aggregations, projections, indexers and conditions (Orders(Status = 'Done'):sum(Total)).
  • Batched and chained: one request per distributed key and dependency level, with distinct ids, however many objects are mapped; chains such as UserId → ProvinceId → CountryId resolve level by level.
  • Data providers: Entity Framework Core and MongoDB.
  • Transports: gRPC, NATS, RabbitMQ, Kafka, Azure Service Bus and Amazon SQS, with retries and supervision.
  • GraphQL integration with HotChocolate.
  • Compile-time checks: Roslyn analyzers for misconfigured profiles and entities.
  • Observable: activities for OpenTelemetry tracing on mapping and data access.
  • Targets .NET 8, 9 and 10.

All FxMap.* packages need to have the same version.

Quick Start

dotnet add package FxMap
// 1. Configure FxMap
builder.Services.AddFxMap(cfg =>
{
    cfg.AddEntitiesFromAssemblyContaining<SomeEntityAssemblyMarker>();
    cfg.AddProfilesFromAssemblyContaining<SomeProfileAssemblyMarker>();
});

// 2. Define a distributed key
public sealed class UserDistributedKey : IDistributedKey;

// 3. Configure the entity with FluentAPI
public class UserConfig : EntityConfigureOf<User>
{
    protected override void Configure()
    {
        Id(x => x.Id);
        DefaultProperty(x => x.Name);
        UseDistributedKey<UserDistributedKey>(); // Or you want to absolute lose coupling, you can use: UseDistributedKey("UserDistributedKey")
        ExposedName(x => x.Email, "UserEmail");
    }
}

// 4. Define a profile for your DTO
public class UserResponseProfile : ProfileOf<UserResponse>
{
    protected override void Configure()
    {
        UseDistributedKey<UserDistributedKey>() // Or you want to absolute lose coupling, you can use: UseDistributedKey("UserDistributedKey")
            .Of(x => x.UserId)
            .For(x => x.UserName)
            .For(x => x.UserEmail, "Email");
    }
}

Expression Examples

public class UserResponseProfile : ProfileOf<UserResponse>
{
    protected override void Configure()
    {
        UseDistributedKey<UserDistributedKey>()
            .Of(x => x.UserId)
            // Simple property access
            .For(x => x.UserEmail, "Email")
            // Navigation properties
            .For(x => x.CountryName, "Country.Name")
            // Filtering
            .For(x => x.CompletedOrders, "Orders(Status = 'Done')")
            // Aggregation
            .For(x => x.TotalSpent, "Orders:sum(Total)")
            // Projection
            .For(x => x.UserDetails, "{Id, Name, Address.City as CityName}")
            // GroupBy
            .For(x => x.OrdersByStatus, "Orders:groupBy(Status).{Status, :count as Count}");
    }
}

For complete expression syntax including filters, indexers, functions, aggregations, boolean functions, coalesce, ternary operators, and more, visit Expression Documentation.

Packages

Package Description .NET Documentation
Core
FxMap FxMap core: profiles, entity configs, the mapper and the expression language 8.0, 9.0, 10.0 fxmapper.net
Data providers
FxMap.EntityFrameworkCore Answers requests from an Entity Framework Core DbContext 8.0, 9.0, 10.0 README
FxMap.MongoDb Answers requests from MongoDB collections 8.0, 9.0, 10.0 README
Integrations
FxMap.HotChocolate Fills GraphQL response types through HotChocolate 8.0, 9.0, 10.0 README
Transports
FxMap.Grpc gRPC transport 8.0, 9.0, 10.0 README
FxMap.Nats NATS transport 8.0, 9.0, 10.0 README
FxMap.RabbitMq RabbitMQ transport 8.0, 9.0, 10.0 README
FxMap.Kafka Apache Kafka transport 8.0, 9.0, 10.0 README
FxMap.Azure.ServiceBus Azure Service Bus transport (Standard / Premium tiers) 8.0, 9.0, 10.0 README
FxMap.Aws.Sqs Amazon SQS transport 8.0, 9.0, 10.0 README
Tooling
FxMap.Analyzers Roslyn analyzer that validates expression strings at compile time 8.0, 9.0, 10.0 README

Performance

FxMap is built to enrich data that lives in other services, so most of a real call is spent waiting on the network. This benchmark removes the network to measure only the mapper itself: FxMap enriches DTOs from an EF Core InMemory database in the same process (no transport), compared with AutoMapper 14 ProjectTo doing a single projected query.

Scenario: each order has a customer (customer → province → country) and 3-5 items (item → product → category). Both sides produce the same OrderDto graph (the benchmark checks that the results are identical).

  • AutoMapper: db.Orders.ProjectTo<OrderDto>(config), one query with joins.
  • FxMap: load the DTOs with only their scalar values and keys, then IDistributedMapper.MapDataAsync(dtos) resolves customer, province, country, product and category through ProfileOf<T> and the EF Core data provider.
Orders AutoMapper ProjectTo FxMap (query + enrich) FxMap time vs AutoMapper FxMap memory vs AutoMapper
10 164 µs / 276 KB 277 µs / 382 KB 1.69× 1.38×
100 2.07 ms / 2.2 MB 1.81 ms / 1.1 MB 0.88× 0.50×
1,000 96.4 ms / 21.4 MB 93.6 ms / 7.0 MB 0.97× 0.33×

BenchmarkDotNet 0.15, 3 launches, .NET 10, Apple M1 Pro. Lower is better.

How to read it:

  • Past a few dozen objects FxMap is on par with or faster than a single joined ProjectTo and allocates a half to a third of the memory, because it fetches each distinct key once instead of joining every row.
  • With a handful of objects both take well under a millisecond; the fixed cost of one scoped query per distributed key and level shows up (about 0.1 ms here) and FxMap is slower in relative terms.
  • At 1,000 orders the in-memory query itself is most of the time (about 84 ms of the 94 ms), so the gap between the two is small there.
  • This is a local, single-process comparison on an in-memory provider. With a real database or transport, the cost of the round trips dominates and FxMap's batching by key is what matters; these numbers say nothing about network latency.

To reproduce:

cd FxMap/test/FxMap.Benchmark
dotnet run -c Release -- --filter '*ProjectionBenchmark*' --launchCount 3

Documentation

Visit fxmapper.net for:

Community

Contributing

Contributions are welcome! See CONTRIBUTING.md or visit our GitHub repository to:

  • Report issues
  • Submit pull requests
  • Request features

License

This project is licensed under the Apache-2.0 license.


Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  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 (10)

Showing the top 5 NuGet packages that depend on FxMap:

Package Downloads
FxMap.EntityFrameworkCore

FxMap extension. Use EntityFramework as Data Querying

FxMap.gRPC

FxMap extension. Use gRPC as Data transporting

FxMap.Nats

Nats.io extension. Use Nats as Data transporting

FxMap.RabbitMq

FxMap.RabbitMq extension. Use RabbitMq as Data transporting

FxMap.Azure.ServiceBus

Azure ServiceBus extension. Use Azure ServiceBus as Data transporting

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.1.1 32 10/6/2026
4.1.0 71 10/5/2026
4.0.0 111 10/5/2026
3.0.0 201 10/2/2026
2.3.5 111 10/2/2026
2.3.4 111 10/2/2026
2.3.3 122 10/1/2026
2.3.2 155 10/1/2026
2.3.1 313 8/21/2026
2.3.0 311 6/16/2026
2.2.2 304 6/3/2026
2.2.1 298 5/31/2026
2.2.0 662 5/26/2026
2.1.1 296 5/26/2026
2.1.0 434 5/7/2026
2.0.1 279 4/5/2026
2.0.0 250 4/5/2026
1.0.3 270 3/15/2026
1.0.2 250 3/7/2026
1.0.1 270 3/6/2026
Loading failed