A new version of Mappa (v10.1.0) has been released.

Mappa 10.1.0 builds on the 10.0.0 foundation with expanded enum mapping, richer parse and format MappaSettings, identity deep-copy and collection buffer options, stronger diagnostics, safer generated code, and a migrated test stack. Documentation now includes a full feature catalog. Full changelog: v10.0.0โ€ฆv10.1.0

Breaking changes

When upgrading from 10.0.0, see the upgrade guide.

MappaSettings rename

  • ForceCaseInsensitivePropertyMap renamed to CaseInsensitivePropertyMap (#257, #260)
    • Update attribute usage: [MappaSettings(CaseInsensitivePropertyMap = BooleanSetting.Enable)]
    • Update .editorconfig: mappa.caseinsensitivepropertymap = enable
    • The legacy .editorconfig key mappa.forcecaseinsensitivepropertymap is no longer supported

Stricter diagnostics

Projects that previously compiled may now fail with new or tightened generator errors:

  • MP00042 โ€” ambiguous invoke-method resolution (#233, #266) โ€” When multiple methods match [MappaInvokeMethod] or a polymorphism InvokeMethod default, the generator reports an error instead of silently selecting the first match.
  • MP00038 โ€” invalid parse style values (#231, #241) โ€” Arbitrary integer DateTimeStyles / NumberStyles values in [MappaSettings] now produce a generator diagnostic instead of being silently decomposed into known flag bits.

Whatโ€™s new

Test infrastructure

  • Migrate to xUnit v3 (#119, #222) โ€” Test projects now use xUnit v3 and Microsoft Testing Platform.
  • Replace FluentAssertions with AwesomeAssertions (#208, #223) โ€” Assertion library updated across all test projects.

New features

  • IdentityMapDeepCopy setting (#14, #267) โ€” Control shallow, deep, and nested same-type copying in identity mappings via [MappaSettings].
  • EnumerableConcreteType setting (#29, #268) โ€” Prefer T[] over List<T> when mapping to sequence-like interface targets (e.g. IEnumerable<T>).
  • DateTimeStyle for parse (#214, #224) โ€” Per-type DateTimeStyles for Parse / ParseExact on DateTime, DateOnly, and TimeOnly.
  • NumberStyles for parse (#215, #226) โ€” Per-type NumberStyles for string-to-numeric Parse conversions.
  • GlobalDateTimeStyle and GlobalNumberStyle (#225, #228) โ€” Shared parse-style defaults applied across date/time and numeric types.

Enum mapping

  • Description attribute support (#15, #16, #265) โ€” Map enums using [Description] for enum-to-string, string-to-enum, and enum-to-enum conversions.
  • Case-insensitive string-to-enum (#17, #258) โ€” Optional case-insensitive matching when parsing strings to enums.
  • Numeric enum-to-enum mapping (#18, #264) โ€” Map enums by numeric value instead of member name via EnumToEnumMapSetting.
  • Partial enum-to-enum warning (MP00039) (#19, #244) โ€” Warn when not all source enum members can be mapped to the target enum.
  • CaseInsensitiveEnumMap (#15, #265) โ€” Optional case-insensitive enum member matching.
  • Rename ForceCaseInsensitivePropertyMap (#257, #260) โ€” Setting renamed to CaseInsensitivePropertyMap; legacy .editorconfig key removed.

[MappaInvokeMethod] attribute

  • Optional SourcePropertyName parameter (#67, #243) โ€” Invoke a method with an explicit source property value instead of the full source object.
  • Ambiguous invoke-method diagnostic (MP00042) (#233, #266) โ€” Report a diagnostic when [MappaInvokeMethod] or polymorphism invoke-method resolution is ambiguous.

Diagnostics and quality

  • Invalid style values (MP00038) (#231, #241) โ€” Diagnose arbitrary integer DateTimeStyles / NumberStyles values in [MappaSettings].
  • Test coverage improvements (#220, #239) โ€” Additional generator, builder, and settings-stack tests for previously uncovered paths.
  • Fix .editorconfig CurrentCulture mapping (#229, #235) โ€” Correct global culture resolution in MappaGlobalOptions.
  • Rename misleading local in CanMapStringToNumber (#234, #242) โ€” Internal readability fix in string strategy detection.

Generated code safety

  • Escape format and culture strings (#230, #236) โ€” User-controlled format and culture strings are safely escaped in generated mapping code.
  • Escape attribute string literals (#232, #237) โ€” User-controlled literals from mapping attributes are escaped in generated code.

Documentation and samples

  • Feature catalog (Documentation/features.md) (#262, #263) โ€” New page listing all Mappa features with links to tutorial, attributes, algorithm, and samples.
  • Generator algorithm documentation alignment (#227, #240) โ€” Algorithm docs and generator README brought in line with the current implementation.
  • Suppress MP00039 in EnumToEnumMapper sample (#259, #261) โ€” Intentional partial enum mapping demonstrated with #pragma warning disable.

Whatโ€™s next

This is a tentative and non exhaustive list of issues that I would like to cover in the upcoming version of Mappa:

Mapping / generator features

  • #255 โ€” Richer enum mapping configuration
  • #250 โ€” Before / after map hooks
  • #249 โ€” Circular reference / reference handling
  • #248 โ€” Generic mapping methods
  • #246 โ€” Reverse / bidirectional mapping
  • #245 โ€” IQueryable projection (ProjectTo)
  • #184 โ€” More relaxed nullability when matching methods
  • #120 โ€” Flattening and unflattening
  • #108 โ€” Allow preventing Enumerable.Count when targeting arrays, Span, and Memory
  • #73 โ€” Support fields, not only properties
  • #34 โ€” Allow choosing .Add vs. the indexer for dictionary-to-dictionary mapping

Language / platform

  • #174 โ€” Support C# 14 extension blocks in static classes (partial classes assumed)

Diagnostics and maintainability

  • #141 โ€” Improved debug feature
  • #238 โ€” Reduce ReportGenerator CRAP score and cyclomatic complexity in Mappa.Generator