😊 Маппинг объектов без рефлексии и без оверхеда

Маппинг между моделями это одна из самых скучных вещей в C#-разработке. AutoMapper решает проблему, но тянет рефлексию в рантайме. FreakyKit.Forge генерирует весь маппинг-код на этапе компиляции через Roslyn source generators.

Вы объявляете partial-метод, библиотека генерирует его реализацию при сборке. Никакой рефлексии, никаких зависимостей в рантайме.

Установка: Как это работает

Помечаем статический класс атрибутом [Forge] и объявляем метод без тела: using FreakyKit.Forge;

public class Person { public string Name { get; set; } public int Age { get; set; } } public class PersonDto { public string Name { get; set; } public int Age { get; set; } }

[Forge] public static partial class PersonForges { public static partial PersonDto ToDto(Person source); }

При компиляции Forge генерирует реализацию: public static partial PersonDto ToDto(Person source) { var __result = new PersonDto(); __result.Name = source.Name; __result.Age = source.Age; return __result; }

Вызов выглядит так: var dto = PersonForges.ToDto(person);

Возможности

Базовый сценарий это маппинг по совпадению имён. Но библиотека умеет больше.

Переименование полей через [ForgeMap]: public class Source { [ForgeMap("Name")] public string FirstName { get; set; } } public class Dest { public string Name { get; set; } }

Вложенные объекты с AllowNestedForging: [Forge] public static partial class PersonForges { public static partial AddressDto ToAddressDto(Address source);

[ForgeMethod(AllowNestedForging = true)] public static partial PersonDto ToDto(Person source); } // Генерирует: __result.Home = ToAddressDto(source.Home);

Коллекции обрабатываются автоматически — List, T[], ImmutableArray и другие. Если типы элементов отличаются, достаточно включить AllowNestedForging.

Обновление существующего объекта вместо создания нового — метод с двумя параметрами и void: public static partial void Update(Person source, PersonDto existing); // Генерирует: existing.Name = source.Name; existing.Age = source.Age;

Строгий режим для отлова расхождений при рефакторинге: [ForgeMethod(StrictMapping = true)] public static partial PersonDto ToDto(Person source); // Если добавить поле в Source или Dest — компилятор выдаст ошибку, не предупреждение

Тип-конвертеры для несовместимых типов: [ForgeConverter] public static string ConvertDateTime(DateTime value) => value.ToString("yyyy-MM-dd"); // Forge сам найдёт подходящий конвертер и применит его при маппинге

Диагностика

Пакет FreakyKit.Forge.Analyzers добавляет 35 диагностических правил. Ошибки в объявлениях маппингов вы увидите прямо в редакторе при сборке, а не в рантайме.

➡️ Репозиторий

📍 Навигация: Вакансии ЗадачиСобесы 🐸 Библиотека шарписта

#sharp_view


В этом посте были ссылки, но мы их удалили по правилам Сетки