Skip to content

Configuration Reference

Aghogho Bernard edited this page May 12, 2026 · 1 revision

Configuration Reference

The Option class is the single configuration surface for MapCollection. You configure it via the Action<Option> callback passed as the third argument.

RootKey (required)

Type: string Default: null Throws: RootKeyOptionNullException if not set, RootKeyPropertyNullException if the key doesn't resolve in the JSON.

The JSON path that contains the array of items to map. Supports dot notation for nested locations.

options.RootKey = "products";                // root.products[]
options.RootKey = "data.products";           // root.data.products[]
options.RootKey = "response.data.products";  // arbitrarily nested

ItemKey (conditionally required)

Type: string Default: null Required: When the destination list is non-empty and you want to update existing items rather than recreate them. Throws: ItemKeyOptionNullException if Update Mode runs and ItemKey is not set.

The C# property name on your destination type that uniquely identifies each item. The mapper uses this to match incoming JSON rows to existing destination items.

If ItemKey is also listed in Mappings, the mapper will use the mapped JSON path (the dictionary value) when looking up the value in the incoming JSON. This lets ItemKey reference your C# property name even when the JSON key differs.

// JSON: { "products": [{ "product_name": "Widget", "stock": 5 }] }
// C# property: Title

options.ItemKey = "Title";
options.Mappings = new() { { "Title", "product_name" } };
// mapper looks at JSON's "product_name" but matches against C# Title

See Mapping Modes for the full mode-selection logic.

Mappings (optional)

Type: Dictionary<string, string> Default: null

Custom property mappings for the cases where a JSON path differs from your C# property name. Keys are C# property names, values are JSON paths (with optional dot notation).

options.Mappings = new Dictionary<string, string>
{
    { "Email",        "workEmail" },              // simple rename
    { "ManagerEmail", "supervisor.email" },       // nested JSON
    { "Department",   "employment.dept.name" }    // deeply nested
};

Properties not in Mappings are still mapped by direct name match (case-insensitive) — so you only declare the differences.

IsItemEmpty (optional)

Type: Func<object, bool> Default: null

A predicate that determines whether an existing destination item should be considered "empty." When provided, this rule takes precedence over the default ItemKey-based empty detection.

When every item in the destination satisfies IsItemEmpty, the mapper enters Create Mode (rebuilds the list from JSON, dropping existing entries). When any item fails the predicate, the mapper enters Update Mode (matches JSON rows to existing items via ItemKey).

options.IsItemEmpty = item =>
{
    var p = (HRISSyncProfile)item;
    return string.IsNullOrEmpty(p.WorkEmail);
};

Why this exists

Sometimes "is this item real?" needs a more nuanced rule than "is the ItemKey value populated?" Examples:

  • The ItemKey is a non-string property (a numeric ID, a Guid, etc.) and you want a strongly-typed check.
  • "Empty" means several properties are unset, not just one.
  • You have a domain-specific concept of validity (e.g. an "imported but not finalized" flag).

IsItemEmpty decouples the identity concept (ItemKey) from the validity concept.

MappingKeys (read-only)

Type: List<string>

A convenience property that returns the keys of the Mappings dictionary as a list. Used internally; rarely needed in caller code.

Summary table

Property Type Required Purpose
RootKey string Always JSON path to the array of items
ItemKey string For Update Mode C# property that identifies each item
Mappings Dictionary<string, string> When names differ C# property → JSON path
IsItemEmpty Func<object, bool> Optional Custom predicate for emptiness; overrides the default ItemKey check

Clone this wiki locally