Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/DedAnton/NextGenMapper

Extremely fast and lightweight minimalistic object mapper generated on the fly
https://github.com/DedAnton/NextGenMapper

codegenerator csharp dotnet fast mapper mapping source-generators

Last synced: 2 days ago
JSON representation

Extremely fast and lightweight minimalistic object mapper generated on the fly

Awesome Lists containing this project

README

        






License: MIT

GitHub release (latest by date including pre-releases)

donate

Extremely fast and lightweight minimalistic object mapper generated on the fly

https://user-images.githubusercontent.com/36799941/191618500-31f7e179-3510-49dc-ad13-18e07de8309b.mov

# Key features
- Generation of mapping methods on the fly
- Reflection and expression trees are not used
- Performance like a hand-written mapper
- Minimum memory allocation
- Does not increase application startup time
- No dependencies in the final assembly
- No third party tools and IDE dependencies
- Static analysis support
- Code navigation support
- Easy to debug
- No attributes and fluid API

NextGenMapper is a tool that just solves a problem and tries not to create new ones

# Usage

Add `using NextGenMapper` and call the `Map` extension method on the object you want to map
```c#
using NextGenMapper;

var source = new Source("Anton", 25);

var destination = source.Map();

Console.WriteLine(destination);

record Source(string Name, int Age);
record Destination(string Name, int Age);
```

To customize the mapping of certain properties, call the `MapWith` method and pass the value of the overridden property as an argument
```c#
using NextGenMapper;

var source = new Source("Anton", "Ryabchikov", 25);

var destination = source.MapWith(name: source.FirstName + ' ' + source.LastName);

Console.WriteLine(destination);

record Source(string FirstName, string LastName, int Age);
record Destination(string Name, int Age);
```

In order for NextGenMapper to use your mapping when mapping other objects, you need to create a partial class `Mapper` in the `NextGenMapper` namespace and add the `Map` method with your implementation to it
```c#
namespace NextGenMapper;

internal static partial class Mapper
{
internal static Destination Map(this Source source)
=> source.MapWith(name: source.FirstName + ' ' + source.LastName);
}
```

The following collection types are currently supported: `List`, `Array`, `ICollection`, `IEnumerable`, `IList`, `IReadOnlyCollection`, `IReadOnlyList`, `ImmutableArray`, `ImmutableList`, `IImmutableList`
```c#
var sourceCollection = new List { new("Anton", 25) };

var destination = sourceCollection.Map>();
```

Enums can also be mapped
```c#
var source = Source.EnumValue;

var destination = source.Map();
```

Projection for IQueryable supported
```c#
_dbContext.Users.Project().ToList();
```

> **Note**:
> Due to the use of new technology, some versions of Visual Studio can sometimes experience problems with syntax highlighting if IntelliCode says an error, but the solution was build without errors is to simply restart Visual Studio
### Installation

Install from the package manager console:
```
PM> Install-Package NextGenMapper -prerelease
```
Or from the .NET CLI as:
```
dotnet add package NextGenMapper --prerelease
```

# How it works?
NextGenMapper uses the new C# language feature - [Source Code Generators](https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/). You can describe the work of the Source Code Generator in the following steps:
1. Code compiles
2. The source code generator analyzes the assembly
3. Generates new code based on analysis
4. Compiles the new code and adds it to the assembly

This is how the method that is called initially looks like:
```C#
internal static To Map(this object source) => throw new InvalidOperationException($""Error when mapping {source.GetType()} to {typeof(To)}, mapping function was not found. Create custom mapping function."");
```

When we call it, the generator analyzes this call and generates a mapping function:
```C#
internal static Destination Map(this Source source)
=> new Destination(source.Name, source.Age);
```

The trick is that the method signatures are identical, but the generated method has more specific parameters and fits better, so it is called ([this behavior is described in the specification](https://github.com/dotnet/csharplang/blob/a4c9db9a69ae0d1334ed5675e8faca3b7574c0a1/spec/expressions.md#better-function-member))

# Status
At the moment, all the main functionality has been added. But the work isn't over yet.

All tasks can be viewed on the [project board](https://github.com/users/DedAnton/projects/3)

# Thanks
Thanks JetBrains for support ([Licenses for Open Source Development](https://www.jetbrains.com/community/opensource/#support))

![image](https://github.com/DedAnton/NextGenMapper/assets/36799941/11ebcaf2-016b-4044-89a6-a9d446b29056)