Skip to content

Lightweight high-performanced data mapper, based on Reflection.Emit (compiling convert function on the fly). Perhaps it is the fastest mapper implemented on C#

Notifications You must be signed in to change notification settings

Alexander-Protasenya/Tulur.DataMappings

 
 

Repository files navigation

Tulur.DataMappings

Lightweight, high-performanced data mapper, based on .NET expressions. This project will be helpful if you need to convert objects of different types a lot of times. For example, conversion of data-transfer-object to business-object.

This project is a fork of FsMapper. FsMapper is a good implementation of a perfect idea - the system generates special conversion functions. These functions compile dynamically only once and save in memory. The system uses these functions when it is necessary. In this case mapping process works without using Reflection. As a result, mapping works very fast.

New futures

  1. Main feature: you can create custom rules for your mappings. Because by default, the system converts only properties with equal names / types. But in "Real world applications" it is necessary to have a possibility to use custom rules for your mappings.
  2. Checking existence of a default constructor for result type was moved from "Run-time" to "Compile-time". So, if result type does not have a default constructor, application will not be compiled.
  3. Checking existence of a mapping-function before using was added.
  4. Parameter "capacity" for mapping rules was added. It is common feature for .NET collections. It will be useful if you know the exact number of your kinds of mappings.
  5. Better performance.

Usage

This library is available on NuGet:

PM> Install-Package Tulur.DataMappings

Simple example:

// Initialization of DataMapper
DataMapper mapper = new DataMapper(); 

// Default mapping registration: TypeA -> TypeB
mapper.Register<TypeA, TypeB>();

// Mapping
TypeB objB = mapper.Map<TypeA, TypeB>(objA);

If you need to use custom mapping rules, you can use the following ways:

mapper.Register<TypeA, TypeB>((from, to) =>
{
    to.Name = from.Title;
});

Or

// CreateMap() is method of class MappingRules
mapper.Register<TypeA, TypeB>(MappingRules.CreateMap);

The last variant is more preferable if you use a lot of mapping rules. In this case you can create separate class (or several classes) to store all mapping rules.

Custom mapping rule is an ordinary method with signature void MethodName(TypeA source, TypeB dest).

Performance

I had to completely refactor of FsMapper, because I had a lot of ideas for improving it. As a result I managed to make code shorter and increase performance without any loss. I'm happy about it, because FsMapper is the fastest mapper that I saw. It was the fastest mapper :-)

Original benchmark project from FsMapper is used. But version of .NET Core was updated to the stable latest version; All NuGet dependencies were updated to latest. An updated benchmark is exist in this source code.

.NET Core SDK=2.2.108
  [Host]     : .NET Core 2.2.6 (CoreCLR 4.6.27817.03, CoreFX 4.6.27818.02), 64bit RyuJIT
  DefaultJob : .NET Core 2.2.6 (CoreCLR 4.6.27817.03, CoreFX 4.6.27818.02), 64bit RyuJIT
Method Mean Error StdDev
CtorBenchmark 4.133 ns 0.0401 ns 0.0356 ns
FsMapperBenchmark 43.375 ns 0.1930 ns 0.1805 ns
DataMapperBenchmark 37.639 ns 0.0782 ns 0.0731 ns
AutoMapperBenchmark 113.011 ns 0.5304 ns 0.4429 ns
ExpressMapperBenchmark 139.935 ns 2.8134 ns 2.6316 ns
MapsterBenchmark 54.562 ns 0.1719 ns 0.1435 ns
AgileMapperBenchmark 169.747 ns 0.3111 ns 0.2758 ns
ValueInjecterBenchmark 1,600.073 ns 3.0689 ns 2.8706 ns

Remarks

I intentionally rejected the idea of using lambda-style syntax for custom mapping rules (Automapper style). Lambda-style syntax is beauty for simple mapping, but in "Real world applications" it is a big problem, I think. Because it is more difficult to debug, and use it in complex code. If you don't believe me, you can try to write CreateMap() method from test project in lambda-style :-)

I really like lambda-style, but not for tasks like this.

Donation

If my project helps you, you can support my motivation to continue working on this project :-)

Webmoney: Z410376614329 or R181376873839

Yandex.Money: 410012007533568

Ethereum: 0xFcaD676Dc74ea60c2fF9fb623ff7903AC898a32d

About

Lightweight high-performanced data mapper, based on Reflection.Emit (compiling convert function on the fly). Perhaps it is the fastest mapper implemented on C#

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C# 100.0%