Repository navigation
Your First Mapping
A complete step-by-step guide to creating your first data mapping with FxMap, from defining models to executing the mapping with FluentAPI.
1
Start with a simple entity that holds the data you want to expose:
public class User
{
public string Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
public string ProvinceId { get; set; }
}2
A distributed key is the shared contract between the entity config and the DTO profile:
public sealed class UserDistributedKey : IDistributedKey;3
Use EntityConfigureOf<T> to describe what data is exposed:
public class UserConfig : EntityConfigureOf<User>
{
protected override void Configure()
{
Id(x => x.Id);
DefaultProperty(x => x.Name);
UseDistributedKey<UserDistributedKey>();
ExposedName(x => x.Email, "UserEmail");
}
}What this does: Links UserDistributedKey to the User entity, using Id as the lookup key and Name as the default property. Also exposes Email under the alias "UserEmail".
4
Use ProfileOf<T> to declare which properties to auto-populate and from which source:
public class OrderResponseProfile : ProfileOf<OrderResponse>
{
protected override void Configure()
{
UseDistributedKey<UserDistributedKey>()
// UserId on the DTO is the lookup key
.Of(x => x.UserId)
// UserName ← User.Name (DefaultProperty)
.For(x => x.UserName)
// UserEmail ← User.Email (via ExposedName alias)
.For(x => x.UserEmail, "UserEmail")
// UserPhone ← User.PhoneNumber
.For(x => x.UserPhone, "PhoneNumber");
}
}How it works: FxMap reads UserId from the DTO, looks up the User entity linked to UserDistributedKey, then populates UserName, UserEmail, and UserPhone automatically.
5
Inject IDistributedMapper into your service and call MapDataAsync:
public class OrderService
{
private readonly IDistributedMapper _mapper;
private readonly IOrderRepository _orderRepository;
public OrderService(IDistributedMapper mapper, IOrderRepository orderRepository)
{
_mapper = mapper;
_orderRepository = orderRepository;
}
public async Task<OrderResponse> GetOrderAsync(string orderId)
{
var order = await _orderRepository.GetByIdAsync(orderId);
var response = new OrderResponse
{
Id = order.Id,
UserId = order.UserId
};
// FxMap auto-populates UserName, UserEmail, UserPhone
await _mapper.MapDataAsync(response);
return response;
}
}// 1. Entity
public class User
{
public string Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string PhoneNumber { get; set; }
}
// 2. Distributed Key
public sealed class UserDistributedKey : IDistributedKey;
// 3. Entity Config (data-provider side)
public class UserConfig : EntityConfigureOf<User>
{
protected override void Configure()
{
Id(x => x.Id);
DefaultProperty(x => x.Name);
UseDistributedKey<UserDistributedKey>();
ExposedName(x => x.Email, "UserEmail");
}
}
// 4. DTO
public class OrderResponse
{
public string Id { get; set; }
public string UserId { get; set; }
public string UserName { get; set; }
public string UserEmail { get; set; }
public string UserPhone { get; set; }
}
// 5. Profile (consumer side)
public class OrderResponseProfile : ProfileOf<OrderResponse>
{
protected override void Configure()
{
UseDistributedKey<UserDistributedKey>()
.Of(x => x.UserId)
.For(x => x.UserName)
.For(x => x.UserEmail, "UserEmail")
.For(x => x.UserPhone, "PhoneNumber");
}
}
// 6. Use in service
public async Task<OrderResponse> GetOrderAsync(string orderId)
{
var order = await _orderRepository.GetByIdAsync(orderId);
var response = new OrderResponse { Id = order.Id, UserId = order.UserId };
// Magic happens here!
await _mapper.MapDataAsync(response);
return response;
}1
FxMap scans the response object and finds all registered profiles that match its type.
2
It gathers all the ID values (e.g., UserId) that need to be looked up.
3
FxMap makes efficient batch queries — all lookups for the same key are combined into a single request.
4
Using compiled expressions (10x faster than reflection), FxMap populates the declared properties.
You've created your first FxMap mapping with zero boilerplate:
- No manual data fetching logic
- No manual property assignment
- Automatic batch optimization
- Type-safe FluentAPI configuration
- Register FxMap services in Program.cs using AddFxMap(...)
- Register your EntityConfig classes with AddEntitiesFromAssemblyContaining<>()
- Register your Profile classes with AddProfilesFromAssemblyContaining<>()
- The .Of(x => x.UserId) property must exist and be populated before calling MapDataAsync
- Remember to await MapDataAsync() — it is an async operation
Source: https://fxmapper.net/docs/first-mapping/ — the website is always the most up to date version.
Introduction
Getting Started
Configuration
- Service Registration
- Entities & Profiles
- Handlers
- Pipelines
- Strongly Typed IDs
- Error Handling
- Retry Policy
- Supervisor
- Telemetry
- Kestrel (HTTP/2)
- Analyzers
Expressions
- Overview
- Property Access
- Filters, Sorting & Paging
- Functions
- Aggregations
- Projections
- Coalesce & Ternary
- GroupBy
Data Providers
Transports
Integrations
Quality
AI Assistants
Migration
Release Notes