Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
А в автомаппере, поле удалилось, ну и хрен с ним, тихонько игнорируем.
Автомапер, как мне кажется, сложнее внутри, а так идея одна и та же. Следущий шаг — генерация байткода, но это потребует куда больших усилий.
public Expression<Func<TEntity, TDto>> GetMapExpr<TEntity, TDto>()
{
var entityType = typeof(TEntity);
var entityParam = Expression.Parameter(entityType, "x");
var entityProps = entityType.GetProperties();
var dtoType = typeof(TDto);
var dtoProps = dtoType.GetProperties();
var memberExpressions = ... сличение dtoProps и entityProps и построение Expresion.Bind ...
var newDTO = Expression.MemberInit(Expression.New(dtoType), memberExpressions);
var selector = (Expression<Func<TEntity, TDto>>)Expression.Lambda(newDTO, entityParam);
return selector;
}x =>
{
var source = (TIn) x;
return new TOut
{
Property = source.Property;
...
}
}
private Func<object, TOut> BuildConverter(Type sourceType)
{
var parameter = Expression.Parameter(typeof(object), "x");
var source = Expression.Variable(sourceType, "source");
var bindings = sourceType.GetProperties()
.Where(p => _outProperties.ContainsKey(p.Name))
.Select(p => Expression.Bind(_outProperties[p.Name], Expression.Property(source, p)));
var body = Expression.Block(new[] {source},
Expression.Assign(source, Expression.Convert(parameter, sourceType)),
Expression.MemberInit(Expression.New(_outConstructor), bindings));
return Expression.Lambda<Func<object, TOut>>(body, parameter).Compile();
}
Попробуйте FastExpressionCompiler, и не потому что компиляция быстрее (может для вас время старта не важно), а по этому что скомпилированный делегат может быть быстрее. Иногда, значительно.
Свой mapper или немного про ExpressionTrees