Однажды холодным зимним вечером я читал блог Brad Wilson, а именно вот эту статью и понял что нужно писать View-specific models для ASP.NET приложения. Основная проблема с написанием таких моделей заключается в том что приходится писать много “водопроводного кода” для маппинга сущностей базы, возвращаемых ORM на эти самые модели и наоборот. Причем Linq (если поддерживает ORM) позволяет описывать прямое преобразование, но не обратное.

Я начал искать object-to-object мапперы. Сразу нашел AutoMapper, он меня отпугнул монструозностью конфигурации и жутко неудобным (читай статическим) API использования. Кроме того отзывы о скорости работы этого маппера крайне негативные.

Следующим мне на глаза попался EmitMapper. Гораздо более приятный API для использования и довольно высокая скорость работы за счет кодогенерации. Но настройка и кастомизация выполняется очень многословно и непонятно.

В обоих проектах меня не устроил тяжелый API для маппинга. По сути маппинг из типа A в тип B - не более чем функция  A → B, или в нотации типов C# - Func<A,B>.

Я сел писать свой маппер. Естественно для скорости надо заниматься кодогенерацией, но писать свой кодогенератор в несколько килострок кода времени не хватит и проект будет заброшен. Но, к счастью, в .NET начиная с версии 3.5 есть кодогенератор и AST для него. Это классы наследники Expression из пространства имен System.Linq.Expressions, а компилятор тихо сидит в методе Expression<T>.Compile.

Таким образом задача упрощается до безобразия. Необходимо собрать expression tree и скомпилировать его. За два вечера я написал маппер, который поддерживает маппинг массивов, списков, сложных типов, конфигурацию с помощью expression tree и flattering.

Результаты сего труда я залил на Codeplex. Проект назвал Expression Mapper.

Скорость работы мапппера.

Пока писал маппер нашел бенчмарк на хабре. Решил прогнать свой маппер на таком бенчмарке. Результаты немного поразили:

Handwritten Mapper: 88 milliseconds
Emit Mapper: 157 milliseconds
Auto Mapper: 31969 milliseconds
Expression Mapper: 119 milliseconds

Недостатки.

Кроме того что проект еще сырой и требует доработки есть еще один серьезный недостаток. Нету возможности сделать маппер, который не создает новый объект, а изменяет поля в существующем.

Ссылка на страницу проекта - http://expressionmapper.codeplex.com/

Теги : mapping, .NET, Expression Mapper