Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions src/AutoMapper/Execution/ProxyGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,11 @@ private static Type EmitProxy(TypeDescription typeDescription)
var interfaceType = typeDescription.Type;
var additionalProperties = typeDescription.AdditionalProperties;
var propertyNames = string.Join("_", additionalProperties.Select(p => p.Name));
string name =
$"Proxy{propertyNames}<{Regex.Replace(interfaceType.AssemblyQualifiedName ?? interfaceType.FullName ?? interfaceType.Name, @"[\s,]+", "_")}>";
var typeName = $"Proxy_{interfaceType.FullName}_{propertyNames}_{typeDescription.GetHashCode()}";
var allInterfaces = new List<Type> { interfaceType };
allInterfaces.AddRange(interfaceType.GetTypeInfo().ImplementedInterfaces);
Debug.WriteLine(name, "Emitting proxy type");
TypeBuilder typeBuilder = proxyModule.DefineType(name,
Debug.WriteLine(typeName, "Emitting proxy type");
TypeBuilder typeBuilder = proxyModule.DefineType(typeName,
TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.Public, typeof(ProxyBase),
interfaceType.IsInterface() ? new[] { interfaceType } : new Type[0]);
ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public,
Expand Down Expand Up @@ -176,7 +175,11 @@ public TypeDescription(Type type) : this(type, PropertyDescription.Empty)
public TypeDescription(Type type, IEnumerable<PropertyDescription> additionalProperties)
{
Type = type ?? throw new ArgumentNullException(nameof(type));
AdditionalProperties = additionalProperties?.ToArray() ?? throw new ArgumentNullException(nameof(additionalProperties));
if(additionalProperties == null)
{
throw new ArgumentNullException(nameof(additionalProperties));
}
AdditionalProperties = additionalProperties.OrderBy(p => p.Name).ToArray();
}

public Type Type { get; }
Expand Down
36 changes: 32 additions & 4 deletions src/AutoMapper/QueryableExtensions/ExpressionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -504,14 +504,14 @@ public override QueryExpressions GetSubQueryExpression(ExpressionBuilder builder
MapFromSource = path.PropertyMaps.Take(path.PropertyMaps.Length - 1).Select(pm=>pm.SourceMember).MemberAccesses(instanceParameter),
Property = new PropertyDescription
(
string.Join("_", path.PropertyMaps.Select(pm => pm.DestinationProperty.Name)),
string.Join("#", path.PropertyMaps.Select(pm => pm.DestinationProperty.Name)),
path.Last.SourceType
),
Marker = path.Marker
}).ToArray();

var letProperties = letMapInfos.Select(m => m.Property);
var letType = ProxyGenerator.GetSimilarType(request.SourceType, letProperties);
var properties = letMapInfos.Select(m => m.Property).Concat(GetMemberAccessesVisitor.Retrieve(projection, instanceParameter));
var letType = ProxyGenerator.GetSimilarType(typeof(object), properties);
var typeMapFactory = new TypeMapFactory();
TypeMap firstTypeMap;
lock(_configurationProvider)
Expand Down Expand Up @@ -539,9 +539,37 @@ void ReplaceSubQueries()
}
}

class GetMemberAccessesVisitor : ExpressionVisitor
{
private readonly Expression _target;

public List<MemberInfo> Members { get; } = new List<MemberInfo>();

public GetMemberAccessesVisitor(Expression target)
{
_target = target;
}

protected override Expression VisitMember(MemberExpression node)
{
if(node.Expression == _target)
{
Members.Add(node.Member);
}
return base.VisitMember(node);
}

public static IEnumerable<PropertyDescription> Retrieve(Expression expression, Expression target)
{
var visitor = new GetMemberAccessesVisitor(target);
visitor.Visit(expression);
return visitor.Members.Select(member => new PropertyDescription(member.Name, member.GetMemberType()));
}
}

class ReplaceMemberAccessesVisitor : ExpressionVisitor
{
Expression _oldObject, _newObject;
private readonly Expression _oldObject, _newObject;

public ReplaceMemberAccessesVisitor(Expression oldObject, Expression newObject)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

namespace AutoMapper.IntegrationTests
{
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq.Expressions;
using QueryableExtensions;

Expand Down Expand Up @@ -162,6 +163,8 @@ public partial class Product
public bool ECommercePublished { get; set; }
public virtual ICollection<Article> Articles { get; set; }
public int Value { get; }
[NotMapped]
public int NotMappedValue { get; set; }
public virtual List<Article> OtherArticles { get; }
}

Expand Down