Skip to content

Extensions

Leonardo Porro edited this page Jan 31, 2024 · 18 revisions

This library was build to be adapted to any project needs and extended to any ORM or product. If out-of-the-box behavior + configuration is not enough, there are other options, however, a deeper knowledge of the architecture of the library is needed.

Mapping process

The mapper starts with two instances Source and Target (or an instance and a type if Target is null).

IType

When mapping, getting a value from a class source.myProp is not the same as getting it from a dictionary source["myProp"], or any other way of representign an object.

IType is an abstraction that provides constructor, member getter and setter, and also stores mapping metadata (Annotations) for mapping customization.

IType is created by one of the ITypeFactory instances registered in MapperOptions. Is usually called "type" in the code while the original type is refered as "Clr Type" (clrType).

TypePair

Source and Target ITypes are send as parameters to the ITypePairFactory registered in MapperOptions to construct a TypePair with a list of TypePairMember.

A TypePair is the configuration and metadata for a mapping operation between two specific types.

ITypeMapper

ITypeMapperFactory instances registered in MapperOptions construct an ITypeMapper instance from the given TypePair.

Factories have the chance of examining the TypePair instances and check different Source and Target types and Annotations using the CanCreate method. The first factory that returns true will be responsible of creating an ITypeMapper.

There are 3 general groups of object types for the mapper: Primitive, Complex and Collection, dependign on the type, ITypeMapperFactory should also take care of nested ITypeMapper instances. For example, Complex needs a different ITypeMapper for each member and Collection needs an ITypeMapper to apply to each items.

Annotations are used by the mapper to determine if the TypePair can be mapped and to apply special logic when creating the mapper.

Mapping a new thing

Mapper already handles common clr types, dictionaries and Json objects, but if you need to add a new one, such as, for example, Xml nodes, a new IType is needed to define how a member is get from an Xml object, or a value from an Xml element.

Additionally, one or more ITypeMappers will be needed to handle special cases, but usually the built-in ones work.

Take a look at Json mapper to see how mapping from Json nodes to entities was implemented.