Skip to content

Release of v1.0.0

Choose a tag to compare

@tibold tibold released this 14 Mar 09:17
· 92 commits to main since this release

ArchPillar.Extensions.Mapper — v1.0.0

The first release of the ArchPillar Extensions collection ships with a single library: ArchPillar.Extensions.Mapper, an explicit object-to-object DTO mapping and LINQ/EF Core expression projection library for .NET.

Highlights

Explicit, traceable mapping

Every mapper is a named property on a concrete class. Go to Definition, Find All References, and refactoring tools work out of the box — no magic strings, no conventions, no attributes.

Supports both in-memory and IQueryable

A single mapper definition drives both in-memory object mapping (Map()) and LINQ expression projection (Project()). EF Core translates the projection to SQL with no additional configuration.

Nested mappers

Compose mappers for child objects and collections. The library inlines nested expression trees automatically — the LINQ provider sees a single flat expression with no delegate calls.

  • Single object — ChildMapper.Map(src.Child)
  • Collections — src.Items.Project(ChildMapper).ToList()
  • Dictionaries — src.Items.ToDictionary(i => i.Key, i => ChildMapper.Map(i))
  • Conditionals — condition ? MapperA.Map(src.X) : MapperA.Map(src.Y)

Optional properties

Properties declared with .Optional() are excluded by default and included on demand — similar to EF Core's .Include():

.Project(mappers.Order, o => o
    .Include(m => m.CustomerName)
    .Include(m => m.Lines, line => line
        .Include(l => l.SupplierName)))

Both typed lambdas and string paths are supported. In-memory Map() always includes all properties.

Runtime variables

Typed, named placeholders in expressions that are bound at call time:

public Variable<int> CurrentUserId { get; } = CreateVariable<int>();

// In the mapper expression
IsOwner = src.OwnerId == CurrentUserId,

// Bound at call time
.Project(mappers.Order, o => o.Set(mappers.CurrentUserId, currentUser.Id))

Enum mapping

Define enum-to-enum mappings as plain switch expressions. The library generates a LINQ-translatable conditional chain — no throw expressions in the expression tree.

MapTo

Assign mapped properties onto a pre-existing destination instance — useful for updating EF Core tracked entities from commands or DTOs.

Coverage validation

Every destination property must be explicitly mapped, marked optional, or ignored. Three validation modes are available: NonNullableProperties (default), AllProperties, and None. Unmapped properties are caught at build time, not at runtime.

Composable contexts

MapperContext subclasses can be composed via plain constructor injection. No library-specific registration or coupling required.

Supported platforms

  • .NET 8, 9, and 10
  • C# 14

Links