Комментарии 9
т.е. первый раз когда делаете userEntity.MapTo если User не существует, предложило создать класс User с выбором того что включить из UserEntity.
Не уверен что это получиться сделать, поскольку если User не существует, то это будет ошибкой компиляции. А при любой ошибке компиляции Roslyn анализаторы не запускаются.
Возможно это можно как-то обойти через отдельное расшерение для VS, но тогда одним nuget пакетом уже не отделаешься.
По поводу T4, на вход кодогенератору приходят лишь два входных параметра: с какого типа и в какой конвертировать, а из этого много кастомного поведения не получится на мой взгляд. Конечно можно это переделать и расширить, но тогда это будет уже не мапер, а что-то другое.
и самое главное, зачем вообще все мапперы нужны в приципе — это expression-based маппинг, шобы с БД тянуть инфу было удобненько, поэтому нужно обязательно это допилить
Суть автомаппера не банальное перекладывание из одного в другое, в общем-то проекции, возможность инъекции, модульности и расширяемости. Кодогенерация обязывает иметь доступ к методам расширения, в случае автомаппера этого не нужно, требуется только интерфейс IMapper. Пожертвовать всем этим ради нескольких наносекунд не имеет смысла.
А какую потенциальную бизнес задачу можно решить такой модульностью/расширяемостью? Подсунуть реализацию с другой логикой? Звучит очень странно, если логика меняется, то и модель меняется.
Думаю, автор толкал саму идею, наверное, если повозиться с атрибутами то может получится подобие настоящего маппера с инъекциями и расширяемостью(типа аспекта, вешаешь аттрибут который будет реализовывать resolveUsing и прочее). Но пока да, от маппера отказаться сложно из-за тех возможностей ради которых собственно всё и затеяно, прямой маппинг большая редкость.
Я уже повозился с атрибутами. Теперь можно вот так:
public static class UserMapper
{
[AOTMapperMethod]
public static User MapToUser(this IAOTMapper, UserEntity input)
{
var output = new User();
output.Name = input.Name;
output.Age = input.Age;
return output;
}
}
// ...
var mapper = new AOTMapperBuilder()
.AddTestProject() // magic extension method, we will talk about it later
.Build();
var entity = new UserEntity
{
Name = "John",
Age = 30
};
var user = mapper.Map<User>(entity);
Console.WriteLine(user.Name); // John
Console.WriteLine(user.Age); // 30
В придачу маппер еще следит за тем чтобы все пропертя были проинициализированы.
Еще есть на чем работать, но я уже использую где нужен AOT.
Немного больше readme в репозитории.
https://github.com/byme8/AOTMapper
Реализуем AutoMapper при помощи Roslyn и кодогенерации