Repository navigation
Migration Upgrade to 5 1
FxMap 5.1 fixes the retry policy and makes the public API smaller: the configuration is published by interfaces, and the internals are internal.
Do you need this guide?
For the usual use, nothing changes: services.AddFxMap(cfg => ...), IDistributedMapper, profiles, entity configurations, AddEntityFrameworkCore, AddMongoDb, and a transport with a lambda all work as before, because the type of the lambda parameter is inferred, and it is the interface now. Read on if you name a configurator type, use the expression engine, call SetRetryPolicy, or have a package compiled against 5.0.0.
-
The retry policy waits before each retry, calls
onRetrybefore it, throws the last exception, works whenThrowIfException()is not called, and has a newshouldRetry. See Retry Policy. -
The configuration is published by interfaces, and the classes that implement them are
internal sealed. -
The internals of the expression engine and a few other helpers are
internal.
AddFxMap(cfg => ...) and every AddXxx(c => ...) take the interface. If the compiler says that a type is inaccessible, use its interface:
| Public (use these) | Was |
|---|---|
| IMapConfigurator | MapConfigurator |
| IKafkaConfigurator, IRabbitMqConfigurator, ISqsConfigurator, IGrpcClientsConfigurator | KafkaConfigurator, RabbitMqConfigurator, SqsConfigurator, GrpcClientsConfigurator |
| IEfCoreConfigurator, IMongoDbConfigurator, IHotChocolateConfigurator | EfCoreConfigurator, MongoDbConfigurator, HotChocolateConfigurator |
| INatsConfigurator, IAzureServiceBusConfigurator | NatsClientSetting, AzureServiceBusClientSetting |
// 5.0
static void AddMyDefaults(MapConfigurator cfg) { /* ... */ }
// 5.1
static void AddMyDefaults(IMapConfigurator cfg) { /* ... */ }
// 5.0: Action<MapConfigurator> 5.1: Action<IMapConfigurator>The members that only read the settings (ServiceHosts, NatsOption, MaxNestingDepth, SupervisorOptions, ProfileConfigs...) are not part of the interfaces. What AddFxMap returns, for .AddEntityFrameworkCore(...) and .AddMongoDb(...), keeps its members internal. The classes of options that you fill in a callback (RabbitMqCredential, SqsCredential, KafkaSslOptions, FxNatsOpts) are still public.
These are details of the implementation, so they are internal now. There is no replacement: they were never meant to be called from outside.
-
The expression engine: the nodes of the tree (
FilterNode,FunctionNode...),Tokenizer,Token,ExpressionParser,ExpressionParseException,IExpressionNodeVisitor,LinqExpressionBuilder,ProjectionBuilder, andBsonProjectionBuilderof MongoDB. -
Accessors and helpers:
TypeAccessor,ITypeAccessor,PropertyAccessor<,>, the delegatesGetEntityConfig,GetProfileConfig,GetTypeAccessorandMapperDelegates,ReceivedPipelinesOrchestrator,RequestContextImpl,JsonSerializer,ServerSupervisor(IServerSupervisoris still public), and the extension helpers. -
Transports and providers: the gRPC types that Grpc.Tools generates from the
.proto,GrpcServer,GrpcRequestClient,MessageRequestWrappedof NATS, andFieldContextof HotChocolate.
Still public on purpose: IFluentProfileConfig, IFluentEntityConfig and what ProfileOf<T> exposes, the interfaces for custom transports and providers (IRequestClient, IRequestServer, IClientRequestHandler, IQueryOfHandler, QueryHandlerBuilder), and the exceptions.
If you wrote a visitor of the expression tree for 5.0 (the guide told you to drop VisitIndexer), it cannot compile against 5.1: IExpressionNodeVisitor is internal now.
A package that was compiled against 5.0.0 and calls one of the types that left must be compiled again: binary compatibility is not kept for the types that left the public API. Move every FxMap.* package to 5.1.0, as always on the same version.
If you call SetRetryPolicy, read what changed in Retry Policy, and look for these:
-
onRetryreceives the exception of the attempt that failed, and is called before the wait, not after it. It is not called for the last failure. - The exception you catch after the retries is the last one, not the first.
- A request that a local handler answers is no longer retried. Its errors are thrown at once.
- With
ThrowIfException()not called, requests through a transport are now retried, and the error is suppressed only after the last attempt. If you had a retry policy that did nothing, it starts to work, so check the delay and the count.
Add shouldRetry for the failures that are not worth a retry:
cfg.SetRetryPolicy(
retryCount: 3, // retries after the first attempt (at most 4 attempts)
sleepDurationProvider: n => TimeSpan.FromMilliseconds( // waited BEFORE retry n (1 = the first retry)
Random.Shared.Next(0, 200 * (1 << (n - 1)))), // exponential backoff with jitter
onRetry: (ex, delay) => logger.LogWarning(ex, "Retry in {Delay}", delay),
shouldRetry: ex => ex is TimeoutException or IOException); // retry only what can go away- Update every FxMap.* package to 5.1.0 (all on the same version).
- Build. Replace each configurator class the compiler rejects with its interface.
- Remove code that uses the expression engine, ServerSupervisor or the generated gRPC messages.
- Recompile the packages you built against 5.0.0.
- If you call SetRetryPolicy, check onRetry, the exception you catch, and local handlers, and add shouldRetry.
The changelog of the release is docs/changelogs/v5.1.0.md in the repository.
Source: https://fxmapper.net/docs/migrate-to-v5-1/ — 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