Skip to content

FxMap v2.0.0 — Namespace-scoped keys & gRPC-first transport

Choose a tag to compare

@quyvu01 quyvu01 released this 05 Apr 16:58

⚠️ Breaking release. See the Migration Guide below before upgrading from 1.x.

Breaking Changes

1. UseDistributedKey string overload now requires a namespace

Before (1.x):

UseDistributedKey("UserKey");

After (2.0):

UseDistributedKey("UserKey", "MyService");

Both key and namespace are validated by regex at startup. The runtime cache key changes from a plain string to a (key, namespace) tuple, preventing name collisions across services.

2. AddHandlersFromNamespaceContaining removed

Pipeline behaviors are now the only handler registration mechanism. Remove any call to AddHandlersFromNamespaceContaining from your AddFxMap(...) setup.

3. gRPC extension renamed

// Before
app.MapFxMapGrpcService();
// After
app.MapFxMapperGrpc();

4. gRPC delegate renamed

GetFxMapResponseFunc → GetMapperResponseFunc

5. GetAssemblyName() extension removed

Use the standard AssemblyQualifiedName property directly.

6. Removed members

Member Reason
MapConfigurator.AddHandlersFromNamespaceContaining Pipelines are the only registration path
TypeExtensions.IsInterfaceOrConcreteClass Unused internal helper
TypeExtensions.IsFSharpType Unused internal helper
MessageRequestWrapped.Subject Replaced by string-based routing
GetAssemblyName() extension Use AssemblyQualifiedName

New Features

Namespace-scoped string distributed keys

String-based UseDistributedKey calls are now scoped to a {namespace}.{key} pair, preventing cross-service name collisions. IFluentEntityConfig gains a new DistributedNamespace property.

Centralized type lookup

DistributedTypeData record and ConfigurationExtensions.GetDistributedTypeData (with ConcurrentDictionary cache) replace per-transport Type.GetType() lookups. Dynamic types cannot be re-resolved by name at runtime — all transports now go through this single method.

DistributedMapException type

New typed exception class for catching mapping-specific runtime failures.


Improvements

  • gRPC transport fully string-based — discovery and dispatch pipeline operates on AssemblyQualifiedName strings instead of Type[], making it compatible with dynamically-emitted types.
  • Primary constructors — SqsRequestClient, NatsRequestClient, RabbitMqRequestClient migrated to C# primary constructors.
  • Sample updated — Service2 and Service3 expose Kestrel HTTP/2 endpoints with MapFxMapperGrpc() as the default transport.

Migration Guide

Step 1 — Add namespace to all string UseDistributedKey calls

// Before
UseDistributedKey("SomeKey");
// After
UseDistributedKey("SomeKey", "YourServiceName");

Step 2 — Remove AddHandlersFromNamespaceContaining

// Remove:
cfg.AddHandlersFromNamespaceContaining<IAssemblyMarker>();

Step 3 — Rename gRPC extension

// Before
app.MapFxMapGrpcService();
// After
app.MapFxMapperGrpc();

Step 4 — Update delegate references

GetFxMapResponseFunc → GetMapperResponseFunc

Full changelog: docs/changelogs/v2.0.0.md