😊 Маппинг объектов без рефлексии и без оверхеда
Маппинг между моделями это одна из самых скучных вещей в 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 диагностических правил. Ошибки в объявлениях маппингов вы увидите прямо в редакторе при сборке, а не в рантайме.
➡️ Репозиторий
📍 Навигация: Вакансии • Задачи • Собесы 🐸 Библиотека шарписта
В этом посте были ссылки, но мы их удалили по правилам Сетки