{"id":13629366,"url":"https://github.com/DedAnton/NextGenMapper","last_synced_at":"2025-04-17T09:33:23.799Z","repository":{"id":61912205,"uuid":"387057794","full_name":"DedAnton/NextGenMapper","owner":"DedAnton","description":"Extremely fast and lightweight minimalistic object mapper generated on the fly","archived":false,"fork":false,"pushed_at":"2025-03-27T13:57:37.000Z","size":949,"stargazers_count":42,"open_issues_count":17,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-27T14:37:54.847Z","etag":null,"topics":["codegenerator","csharp","dotnet","fast","mapper","mapping","source-generators"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DedAnton.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-07-18T00:02:31.000Z","updated_at":"2025-03-27T13:39:38.000Z","dependencies_parsed_at":"2023-01-20T21:17:47.581Z","dependency_job_id":"ff1b2af3-01b4-4523-9d1e-d0b1ca871cbe","html_url":"https://github.com/DedAnton/NextGenMapper","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DedAnton%2FNextGenMapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DedAnton%2FNextGenMapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DedAnton%2FNextGenMapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DedAnton%2FNextGenMapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DedAnton","download_url":"https://codeload.github.com/DedAnton/NextGenMapper/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249331615,"owners_count":21252618,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["codegenerator","csharp","dotnet","fast","mapper","mapping","source-generators"],"created_at":"2024-08-01T22:01:08.645Z","updated_at":"2025-04-17T09:33:22.852Z","avatar_url":"https://github.com/DedAnton.png","language":"C#","readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"https://user-images.githubusercontent.com/36799941/191375272-27b0034d-0418-44a6-95c6-802b863de2b3.svg\" width=\"242\" height=\"242\"\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/License-MIT-yellow.svg\" alt=\"License: MIT\"\u003e\n    \u003c/a\u003e\n    \u003cimg alt=\"GitHub release (latest by date including pre-releases)\" src=\"https://img.shields.io/github/v/release/DedAnton/NextGenMapper?include_prereleases\"\u003e\n    \u003ca href=\"https://vk.com/away.php?utf=1\u0026to=https%3A%2F%2Fwww.tinkoff.ru%2Fcf%2F3ySZ9DEsxfL\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/%24-donate-9cf\" alt=\"donate\"\u003e\n    \u003c/a\u003e\n    \u003ch4 align=\"center\"\u003eExtremely fast and lightweight minimalistic object mapper generated on the fly\u003c/h4\u003e\n\u003c/p\u003e\n\nhttps://user-images.githubusercontent.com/36799941/191618500-31f7e179-3510-49dc-ad13-18e07de8309b.mov\n\n# Key features\n- Generation of mapping methods on the fly\n- Reflection and expression trees are not used\n- Performance like a hand-written mapper\n- Minimum memory allocation\n- Does not increase application startup time\n- No dependencies in the final assembly\n- No third party tools and IDE dependencies\n- Static analysis support\n- Code navigation support\n- Easy to debug\n- No attributes and fluid API\n\nNextGenMapper is a tool that just solves a problem and tries not to create new ones\n\n# Usage\n\nAdd `using NextGenMapper` and call the `Map` extension method on the object you want to map\n```c#\nusing NextGenMapper;\n\nvar source = new Source(\"Anton\", 25);\n\nvar destination = source.Map\u003cDestination\u003e();\n\nConsole.WriteLine(destination);\n\nrecord Source(string Name, int Age);\nrecord Destination(string Name, int Age);\n```\n\u003cbr\u003e\n\nTo customize the mapping of certain properties, call the `MapWith` method and pass the value of the overridden property as an argument\n```c#\nusing NextGenMapper;\n\nvar source = new Source(\"Anton\", \"Ryabchikov\", 25);\n\nvar destination = source.MapWith\u003cDestination\u003e(name: source.FirstName + ' ' + source.LastName);\n\nConsole.WriteLine(destination);\n\nrecord Source(string FirstName, string LastName, int Age);\nrecord Destination(string Name, int Age);\n```\n\u003cbr\u003e\n\nIn 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\n```c#\nnamespace NextGenMapper;\n\ninternal static partial class Mapper\n{\n    internal static Destination Map\u003cTo\u003e(this Source source) \n        =\u003e source.MapWith\u003cDestination\u003e(name: source.FirstName + ' ' + source.LastName);\n}\n```\n\u003cbr\u003e\n\nThe following collection types are currently supported: `List\u003cT\u003e`, `Array\u003cT\u003e`, `ICollection\u003cT\u003e`, `IEnumerable\u003cT\u003e`, `IList\u003cT\u003e`, `IReadOnlyCollection\u003cT\u003e`, `IReadOnlyList\u003cT\u003e`, `ImmutableArray\u003cT\u003e`, `ImmutableList\u003cT\u003e`, `IImmutableList\u003cT\u003e`\n```c#\nvar sourceCollection = new List\u003cSource\u003e { new(\"Anton\", 25) };\n\nvar destination = sourceCollection.Map\u003cList\u003cDestination\u003e\u003e();\n```\n\u003cbr\u003e\n\nEnums can also be mapped\n```c#\nvar source = Source.EnumValue;\n\nvar destination = source.Map\u003cDestination\u003e();\n```\n\u003cbr\u003e\n\nProjection for IQueryable supported\n```c#\n_dbContext.Users.Project\u003cUserDestination\u003e().ToList();\n```\n\u003cbr\u003e\n\n\u003e **Note**: \n\u003e 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\n### Installation\n\nInstall from the package manager console:\n```\nPM\u003e Install-Package NextGenMapper -prerelease\n```\nOr from the .NET CLI as:\n```\ndotnet add package NextGenMapper --prerelease\n```\n\n# How it works?\nNextGenMapper 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:\n1. Code compiles\n2. The source code generator analyzes the assembly\n3. Generates new code based on analysis\n4. Compiles the new code and adds it to the assembly\n\nThis is how the method that is called initially looks like:\n```C#\ninternal static To Map\u003cTo\u003e(this object source) =\u003e throw new InvalidOperationException($\"\"Error when mapping {source.GetType()} to {typeof(To)}, mapping function was not found. Create custom mapping function.\"\");\n```\n\nWhen we call it, the generator analyzes this call and generates a mapping function:\n```C#\ninternal static Destination Map\u003cTo\u003e(this Source source) \n    =\u003e new Destination(source.Name, source.Age);\n```\n\nThe 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))\n\n# Status\nAt the moment, all the main functionality has been added. But the work isn't over yet.\n\nAll tasks can be viewed on the [project board](https://github.com/users/DedAnton/projects/3)\n\n# Thanks\nThanks JetBrains for support ([Licenses for Open Source Development](https://www.jetbrains.com/community/opensource/#support))\n\n![image](https://github.com/DedAnton/NextGenMapper/assets/36799941/11ebcaf2-016b-4044-89a6-a9d446b29056)\n\n\n\n","funding_links":[],"categories":["Content","Source Generators"],"sub_categories":["46. [NextGenMapper](https://ignatandrei.github.io/RSCG_Examples/v2/docs/NextGenMapper) , in the [Mapper](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#mapper) category","Mappers"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDedAnton%2FNextGenMapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDedAnton%2FNextGenMapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDedAnton%2FNextGenMapper/lists"}