Skip to content

Commit f8f6cbe

Browse files
Merge pull request #106 from Tasteful/use-service-ctor
Use ServiceCtor in EquivalentExpressions.SetGeneratePropertyMaps
2 parents 1e8672b + f9ee4cc commit f8f6cbe

File tree

1 file changed

+38
-21
lines changed

1 file changed

+38
-21
lines changed

src/AutoMapper.Collection/EquivalencyExpression/EquivalentExpressions.cs

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,17 @@ namespace AutoMapper.EquivalencyExpression
1111
{
1212
public static class EquivalentExpressions
1313
{
14-
private static readonly
15-
ConcurrentDictionary<IConfigurationProvider, ConcurrentDictionary<TypePair, IEquivalentComparer>>
16-
EquivalentExpressionDictionary =
17-
new ConcurrentDictionary<IConfigurationProvider, ConcurrentDictionary<TypePair, IEquivalentComparer>>();
14+
private static readonly ConcurrentDictionary<IConfigurationProvider, ConcurrentDictionary<TypePair, IEquivalentComparer>>
15+
_equivalentExpressionDictionary = new ConcurrentDictionary<IConfigurationProvider, ConcurrentDictionary<TypePair, IEquivalentComparer>>();
1816

19-
private static ConcurrentDictionary<TypePair, IEquivalentComparer> _equalityComparisonCache = new ConcurrentDictionary<TypePair, IEquivalentComparer>();
17+
private static readonly ConcurrentDictionary<IConfigurationProvider, IList<IGeneratePropertyMaps>>
18+
_generatePropertyMapsDictionary = new ConcurrentDictionary<IConfigurationProvider, IList<IGeneratePropertyMaps>>();
2019

21-
private static readonly ConcurrentDictionary<IConfigurationProvider, IList<IGeneratePropertyMaps>> GeneratePropertyMapsDictionary = new ConcurrentDictionary<IConfigurationProvider, IList<IGeneratePropertyMaps>>();
22-
private static IList<IGeneratePropertyMaps> _generatePropertyMapsCache = new List<IGeneratePropertyMaps>();
20+
private static ConcurrentDictionary<TypePair, IEquivalentComparer>
21+
_equalityComparisonCache = new ConcurrentDictionary<TypePair, IEquivalentComparer>();
22+
23+
private static IList<Func<Func<Type, object>, IGeneratePropertyMaps>>
24+
_generatePropertyMapsCache = new List<Func<Func<Type, object>, IGeneratePropertyMaps>>();
2325

2426
public static void AddCollectionMappers(this IMapperConfigurationExpression cfg)
2527
{
@@ -35,17 +37,24 @@ private static void InsertBefore<TObjectMapper>(this IMapperConfigurationExpress
3537
var targetMapper = mappers.FirstOrDefault(om => om is TObjectMapper);
3638
var index = targetMapper == null ? 0 : mappers.IndexOf(targetMapper);
3739
foreach (var mapper in adds.Reverse())
40+
{
3841
mappers.Insert(index, mapper);
42+
}
43+
3944
cfg.Advanced.BeforeSeal(c =>
4045
{
4146
foreach (var configurationObjectMapper in adds)
47+
{
4248
configurationObjectMapper.ConfigurationProvider = c;
49+
}
4350

44-
EquivalentExpressionDictionary.AddOrUpdate(c, _equalityComparisonCache, (type, old) => _equalityComparisonCache);
51+
var propertyMapsGenerators = _generatePropertyMapsCache.Select(x => x?.Invoke(c.ServiceCtor)).ToList();
52+
53+
_equivalentExpressionDictionary.AddOrUpdate(c, _equalityComparisonCache, (_, __) => _equalityComparisonCache);
4554
_equalityComparisonCache = new ConcurrentDictionary<TypePair, IEquivalentComparer>();
4655

47-
GeneratePropertyMapsDictionary.AddOrUpdate(c, _generatePropertyMapsCache, (type, old) => _generatePropertyMapsCache);
48-
_generatePropertyMapsCache = new List<IGeneratePropertyMaps>();
56+
_generatePropertyMapsDictionary.AddOrUpdate(c, propertyMapsGenerators, (_, __) => propertyMapsGenerators);
57+
_generatePropertyMapsCache = new List<Func<Func<Type, object>, IGeneratePropertyMaps>>();
4958
});
5059
}
5160

@@ -80,9 +89,10 @@ internal static IEquivalentComparer GetEquivalentExpression(this IConfigurationO
8089

8190
internal static IEquivalentComparer GetEquivalentExpression(IConfigurationProvider configurationProvider, TypeMap typeMap)
8291
{
83-
return EquivalentExpressionDictionary[configurationProvider].GetOrAdd(typeMap.Types,
84-
tp =>
85-
GeneratePropertyMapsDictionary[configurationProvider].Select(_ => _.GeneratePropertyMaps(typeMap).CreateEquivalentExpression()).FirstOrDefault(_ => _ != null));
92+
return _equivalentExpressionDictionary[configurationProvider].GetOrAdd(typeMap.Types, _
93+
=> _generatePropertyMapsDictionary[configurationProvider]
94+
.Select(x => x.GeneratePropertyMaps(typeMap).CreateEquivalentExpression())
95+
.FirstOrDefault(x => x != null));
8696
}
8797

8898
/// <summary>
@@ -98,42 +108,49 @@ public static IMappingExpression<TSource, TDestination> EqualityComparison<TSour
98108
where TDestination : class
99109
{
100110
var typePair = new TypePair(typeof(TSource), typeof(TDestination));
111+
101112
_equalityComparisonCache.AddOrUpdate(typePair,
102113
new EquivalentExpression<TSource, TDestination>(EquivalentExpression),
103-
(type, old) => new EquivalentExpression<TSource, TDestination>(EquivalentExpression));
114+
(_, __) => new EquivalentExpression<TSource, TDestination>(EquivalentExpression));
115+
104116
return mappingExpression;
105117
}
106118

107119
public static void SetGeneratePropertyMaps<TGeneratePropertyMaps>(this IMapperConfigurationExpression cfg)
108-
where TGeneratePropertyMaps : IGeneratePropertyMaps, new()
120+
where TGeneratePropertyMaps : IGeneratePropertyMaps
109121
{
110-
cfg.SetGeneratePropertyMaps(new TGeneratePropertyMaps());
122+
_generatePropertyMapsCache.Add(serviceCtor => (IGeneratePropertyMaps)serviceCtor(typeof(TGeneratePropertyMaps)));
111123
}
112124

113125
public static void SetGeneratePropertyMaps(this IMapperConfigurationExpression cfg, IGeneratePropertyMaps generatePropertyMaps)
114126
{
115-
_generatePropertyMapsCache.Add(generatePropertyMaps);
127+
_generatePropertyMapsCache.Add(_ => generatePropertyMaps);
116128
}
117129

118130
private static IEquivalentComparer CreateEquivalentExpression(this IEnumerable<PropertyMap> propertyMaps)
119131
{
120132
if (!propertyMaps.Any() || propertyMaps.Any(pm => pm.DestinationProperty.GetMemberType() != pm.SourceMember.GetMemberType()))
133+
{
121134
return null;
135+
}
136+
122137
var typeMap = propertyMaps.First().TypeMap;
123138
var srcType = typeMap.SourceType;
124139
var destType = typeMap.DestinationType;
125140
var srcExpr = Expression.Parameter(srcType, "src");
126141
var destExpr = Expression.Parameter(destType, "dest");
127142

128143
var equalExpr = propertyMaps.Select(pm => SourceEqualsDestinationExpression(pm, srcExpr, destExpr)).ToList();
129-
if (!equalExpr.Any())
144+
if (equalExpr.Count == 0)
145+
{
130146
return EquivalentExpression.BadValue;
131-
var finalExpression = equalExpr.Skip(1).Aggregate(equalExpr.First(), Expression.And);
147+
}
148+
149+
var finalExpression = equalExpr.Skip(1).Aggregate(equalExpr[0], Expression.And);
132150

133151
var expr = Expression.Lambda(finalExpression, srcExpr, destExpr);
134152
var genericExpressionType = typeof(EquivalentExpression<,>).MakeGenericType(srcType, destType);
135-
var equivilientExpression = Activator.CreateInstance(genericExpressionType, expr) as IEquivalentComparer;
136-
return equivilientExpression;
153+
return Activator.CreateInstance(genericExpressionType, expr) as IEquivalentComparer;
137154
}
138155

139156
private static BinaryExpression SourceEqualsDestinationExpression(PropertyMap propertyMap, Expression srcExpr, Expression destExpr)

0 commit comments

Comments
 (0)