Skip to content

Commit ca76ebc

Browse files
committed
seal lazily if there are no included maps
1 parent 21b0636 commit ca76ebc

File tree

7 files changed

+61
-56
lines changed

7 files changed

+61
-56
lines changed

src/AutoMapper/Configuration/MapperConfiguration.cs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,10 @@ void Seal()
131131
}
132132
foreach (var typeMap in _configuredMaps.Values)
133133
{
134-
typeMap.Seal(this);
134+
if (typeMap.HasIncludedMembers || typeMap.IncludedBaseTypes.Count > 0)
135+
{
136+
typeMap.Seal(this);
137+
}
135138
}
136139
_features.Seal(this);
137140
}
@@ -283,24 +286,27 @@ public static AutoMapperMappingException GetMappingError(Exception innerExceptio
283286
TypeMap IGlobalConfiguration.ResolveTypeMap(TypePair typePair) => ResolveTypeMap(typePair);
284287
TypeMap ResolveTypeMap(TypePair typePair)
285288
{
286-
if (_resolvedMaps.TryGetValue(typePair, out TypeMap typeMap))
287-
{
288-
return typeMap;
289-
}
289+
TypeMap typeMap;
290290
if (_runtimeMaps.IsDefault)
291291
{
292-
typeMap = GetTypeMap(typePair);
293-
_resolvedMaps.Add(typePair, typeMap);
294-
if (typeMap != null && typeMap.MapExpression == null)
292+
if (!_resolvedMaps.TryGetValue(typePair, out typeMap))
293+
{
294+
typeMap = GetTypeMap(typePair);
295+
_resolvedMaps.Add(typePair, typeMap);
296+
}
297+
if (typeMap != null && !typeMap.Projection && typeMap.MapExpression == null)
295298
{
296299
typeMap.Seal(this);
297300
}
298301
}
299302
else
300303
{
301-
typeMap = _runtimeMaps.GetOrAdd(typePair);
304+
if (!_resolvedMaps.TryGetValue(typePair, out typeMap))
305+
{
306+
typeMap = _runtimeMaps.GetOrAdd(typePair);
307+
}
302308
// if it's a dynamically created type map, we need to seal it outside GetTypeMap to handle recursion
303-
if (typeMap != null && typeMap.MapExpression == null)
309+
if (typeMap != null && !typeMap.Projection && typeMap.MapExpression == null)
304310
{
305311
lock (typeMap)
306312
{

src/AutoMapper/Execution/TypeMapPlanBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ private static void CheckForCycles(IGlobalConfiguration configuration, TypeMap t
9696
memberMap.Inline = false;
9797
TraceInline(typeMap, memberMap);
9898
}
99-
if (memberTypeMap.PreserveReferences || memberTypeMap.MapExpression != null)
99+
if (memberTypeMap.PreserveReferences)
100100
{
101101
continue;
102102
}

src/UnitTests/AutoMapperSpecBase.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ IMapper CreateMapper()
2323
protected virtual void OnConfig(MapperConfiguration mapperConfiguration) { }
2424
protected TDestination Map<TDestination>(object source) => Mapper.Map<TDestination>(source);
2525
protected TypeMap FindTypeMapFor<TSource, TDestination>() => Configuration.FindTypeMapFor<TSource, TDestination>();
26+
protected TypeMap ResolveTypeMap<TSource, TDestination>() => Configuration.ResolveTypeMap<TSource, TDestination>();
2627
protected virtual void AssertConfigurationIsValid() => Configuration.AssertConfigurationIsValid();
2728
protected void AssertConfigurationIsValid<TSource, TDestination>() => Configuration.AssertConfigurationIsValid(Configuration.FindTypeMapFor<TSource, TDestination>());
2829
protected void AssertConfigurationIsValid(Type sourceType, Type destinationType) => Configuration.AssertConfigurationIsValid(Configuration.FindTypeMapFor(sourceType, destinationType));
@@ -50,6 +51,7 @@ public static IMappingExpression<TSource, TDestination> Advanced<TSource, TDesti
5051
(IMappingExpression<TSource, TDestination>)projection;
5152
public static TypeMap FindTypeMapFor<TSource, TDestination>(this IConfigurationProvider configurationProvider) => configurationProvider.Internal().FindTypeMapFor<TSource, TDestination>();
5253
public static IReadOnlyCollection<TypeMap> GetAllTypeMaps(this IConfigurationProvider configurationProvider) => configurationProvider.Internal().GetAllTypeMaps();
54+
public static TypeMap ResolveTypeMap<TSource, TDestination>(this IConfigurationProvider configurationProvider) => configurationProvider.Internal().ResolveTypeMap(typeof(TSource), typeof(TDestination));
5355
public static TypeMap ResolveTypeMap(this IConfigurationProvider configurationProvider, Type sourceType, Type destinationType) => configurationProvider.Internal().ResolveTypeMap(sourceType, destinationType);
5456
public static void ForAllMaps(this IMapperConfigurationExpression configurationProvider, Action<TypeMap, IMappingExpression> configuration) => configurationProvider.Internal().ForAllMaps(configuration);
5557
public static void ForAllPropertyMaps(this IMapperConfigurationExpression configurationProvider, Func<PropertyMap, bool> condition, Action<PropertyMap, IMemberConfigurationExpression> memberOptions) =>

src/UnitTests/ForPath.cs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -250,15 +250,12 @@ public class SourceModel
250250
[Fact]
251251
public void Should_throw_exception()
252252
{
253-
Assert.Throws<NullReferenceException>(() =>
253+
var cfg = new MapperConfiguration(config =>
254254
{
255-
var cfg = new MapperConfiguration(config =>
255+
Assert.Throws<ArgumentNullException>(() =>
256256
{
257-
Assert.Throws<ArgumentNullException>(() =>
258-
{
259-
config.CreateMap<SourceModel, DestinationModel>()
260-
.ForPath(sourceModel => sourceModel.Name, opts => opts.MapFrom<string>(null));
261-
});
257+
config.CreateMap<SourceModel, DestinationModel>()
258+
.ForPath(sourceModel => sourceModel.Name, opts => opts.MapFrom<string>(null));
262259
});
263260
});
264261
}

src/UnitTests/MappingExpressionFeatureWithReverseTest.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ public void Adding_same_feature_multiple_times_should_replace_eachother()
2222
});
2323

2424

25-
var typeMap = config.FindTypeMapFor<Source, Dest>();
25+
var typeMap = config.ResolveTypeMap<Source, Dest>();
2626
typeMap.Features.Count.ShouldBe(2);
2727

28-
var typeMapReverse = config.FindTypeMapFor<Dest, Source>();
28+
var typeMapReverse = config.ResolveTypeMap<Dest, Source>();
2929
typeMapReverse.Features.Count.ShouldBe(2);
3030

3131
Validate(featureA);
@@ -49,10 +49,10 @@ public void Add_single_feature_with_reverse()
4949
.ReverseMap();
5050
});
5151

52-
var typeMap = config.FindTypeMapFor<Source, Dest>();
52+
var typeMap = config.ResolveTypeMap<Source, Dest>();
5353
typeMap.Features.Count.ShouldBe(1);
5454

55-
var typeMapReverse = config.FindTypeMapFor<Dest, Source>();
55+
var typeMapReverse = config.ResolveTypeMap<Dest, Source>();
5656
typeMapReverse.Features.Count.ShouldBe(1);
5757

5858
Validate<TypeMapFeatureA>(featureA);
@@ -88,10 +88,10 @@ public void Add_multiple_features_with_reverse()
8888
.ReverseMap();
8989
});
9090

91-
var typeMap = config.FindTypeMapFor<Source, Dest>();
91+
var typeMap = config.ResolveTypeMap<Source, Dest>();
9292
typeMap.Features.Count.ShouldBe(2);
9393

94-
var typeMapReverse = config.FindTypeMapFor<Dest, Source>();
94+
var typeMapReverse = config.ResolveTypeMap<Dest, Source>();
9595
typeMapReverse.Features.Count.ShouldBe(2);
9696

9797
Validate<TypeMapFeatureA>(featureA);
@@ -130,10 +130,10 @@ public void Add_multiple_features_with_reverse_overriden()
130130
.SetFeature(overridenFeatureB);
131131
});
132132

133-
var typeMap = config.FindTypeMapFor<Source, Dest>();
133+
var typeMap = config.ResolveTypeMap<Source, Dest>();
134134
typeMap.Features.Count.ShouldBe(2);
135135

136-
var typeMapReverse = config.FindTypeMapFor<Dest, Source>();
136+
var typeMapReverse = config.ResolveTypeMap<Dest, Source>();
137137
typeMapReverse.Features.Count.ShouldBe(2);
138138

139139
Validate<TypeMapFeatureA>(featureA, typeMap);

src/UnitTests/MappingExpressionFeatureWithoutReverseTest.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public void Adding_same_feature_should_replace_eachother()
2222
});
2323

2424

25-
var typeMap = config.FindTypeMapFor<Source, Dest>();
25+
var typeMap = config.ResolveTypeMap<Source, Dest>();
2626
typeMap.Features.Count.ShouldBe(2);
2727

2828
var typeMapReverse = config.ResolveTypeMap(typeof(Dest), typeof(Source));
@@ -49,7 +49,7 @@ public void Add_single_feature()
4949
.ReverseMap();
5050
});
5151

52-
var typeMap = config.FindTypeMapFor<Source, Dest>();
52+
var typeMap = config.ResolveTypeMap<Source, Dest>();
5353
typeMap.Features.Count.ShouldBe(1);
5454

5555
var typeMapReverse = config.ResolveTypeMap(typeof(Dest), typeof(Source));
@@ -81,10 +81,10 @@ public void Add_single_feature_with_reverse()
8181
.ReverseMap();
8282
});
8383

84-
var typeMap = config.FindTypeMapFor<Source, Dest>();
84+
var typeMap = config.ResolveTypeMap<Source, Dest>();
8585
typeMap.Features.Count.ShouldBe(1);
8686

87-
var typeMapReverse = config.FindTypeMapFor<Dest, Source>();
87+
var typeMapReverse = config.ResolveTypeMap<Dest, Source>();
8888
typeMapReverse.Features.Count.ShouldBe(0);
8989

9090
Validate<TypeMapFeatureA>(featureA);
@@ -116,7 +116,7 @@ public void Add_multiple_features()
116116
});
117117

118118

119-
var typeMap = config.FindTypeMapFor<Source, Dest>();
119+
var typeMap = config.ResolveTypeMap<Source, Dest>();
120120
typeMap.Features.Count.ShouldBe(2);
121121

122122
var typeMapReverse = config.ResolveTypeMap(typeof(Dest), typeof(Source));
@@ -151,10 +151,10 @@ public void Add_multiple_features_with_reverse()
151151
.ReverseMap();
152152
});
153153

154-
var typeMap = config.FindTypeMapFor<Source, Dest>();
154+
var typeMap = config.ResolveTypeMap<Source, Dest>();
155155
typeMap.Features.Count.ShouldBe(2);
156156

157-
var typeMapReverse = config.FindTypeMapFor<Dest, Source>();
157+
var typeMapReverse = config.ResolveTypeMap<Dest, Source>();
158158
typeMapReverse.Features.Count.ShouldBe(0);
159159

160160
Validate<TypeMapFeatureA>(featureA);
@@ -188,10 +188,10 @@ public void Add_multiple_features_with_reverse_overriden()
188188
.SetFeature(overridenFeatureB);
189189
});
190190

191-
var typeMap = config.FindTypeMapFor<Source, Dest>();
191+
var typeMap = config.ResolveTypeMap<Source, Dest>();
192192
typeMap.Features.Count.ShouldBe(2);
193193

194-
var typeMapReverse = config.FindTypeMapFor<Dest, Source>();
194+
var typeMapReverse = config.ResolveTypeMap<Dest, Source>();
195195
typeMapReverse.Features.Count.ShouldBe(1);
196196

197197
Validate<TypeMapFeatureA>(featureA, typeMap);

src/UnitTests/MaxExecutionPlanDepth.cs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -87,19 +87,19 @@ class Destination6
8787
public void Should_set_inline_accordingly()
8888
{
8989
TypeMap map;
90-
map = FindTypeMapFor<Source, Destination>();
90+
map = ResolveTypeMap<Source, Destination>();
9191
map.PropertyMaps.First().Inline.ShouldBeTrue();
92-
map = FindTypeMapFor<Source1, Destination1>();
92+
map = ResolveTypeMap<Source1, Destination1>();
9393
map.PropertyMaps.First().Inline.ShouldBeTrue();
94-
map = FindTypeMapFor<Source2, Destination2>();
94+
map = ResolveTypeMap<Source2, Destination2>();
9595
map.PropertyMaps.First().Inline.ShouldBeFalse();
96-
map = FindTypeMapFor<Source3, Destination3>();
96+
map = ResolveTypeMap<Source3, Destination3>();
9797
map.PropertyMaps.First().Inline.ShouldBeFalse();
98-
map = FindTypeMapFor<Source4, Destination4>();
98+
map = ResolveTypeMap<Source4, Destination4>();
9999
map.PropertyMaps.First().Inline.ShouldBeFalse();
100-
map = FindTypeMapFor<Source5, Destination5>();
100+
map = ResolveTypeMap<Source5, Destination5>();
101101
map.PropertyMaps.First().Inline.ShouldBeFalse();
102-
map = FindTypeMapFor<Source6, Destination6>();
102+
map = ResolveTypeMap<Source6, Destination6>();
103103
map.PropertyMaps.First().Inline.ShouldBeTrue();
104104
}
105105
}
@@ -189,19 +189,19 @@ class Destination6
189189
public void Should_set_inline_accordingly()
190190
{
191191
TypeMap map;
192-
map = FindTypeMapFor<Source, Destination>();
192+
map = ResolveTypeMap<Source, Destination>();
193193
map.PropertyMaps.First().Inline.ShouldBeTrue();
194-
map = FindTypeMapFor<Source1, Destination1>();
194+
map = ResolveTypeMap<Source1, Destination1>();
195195
map.PropertyMaps.First().Inline.ShouldBeFalse();
196-
map = FindTypeMapFor<Source2, Destination2>();
196+
map = ResolveTypeMap<Source2, Destination2>();
197197
map.PropertyMaps.First().Inline.ShouldBeFalse();
198-
map = FindTypeMapFor<Source3, Destination3>();
198+
map = ResolveTypeMap<Source3, Destination3>();
199199
map.PropertyMaps.First().Inline.ShouldBeFalse();
200-
map = FindTypeMapFor<Source4, Destination4>();
200+
map = ResolveTypeMap<Source4, Destination4>();
201201
map.PropertyMaps.First().Inline.ShouldBeFalse();
202-
map = FindTypeMapFor<Source5, Destination5>();
202+
map = ResolveTypeMap<Source5, Destination5>();
203203
map.PropertyMaps.First().Inline.ShouldBeFalse();
204-
map = FindTypeMapFor<Source6, Destination6>();
204+
map = ResolveTypeMap<Source6, Destination6>();
205205
map.PropertyMaps.First().Inline.ShouldBeTrue();
206206
}
207207
}
@@ -293,17 +293,17 @@ class Destination6
293293
public void Should_set_inline_accordingly()
294294
{
295295
TypeMap map;
296-
map = FindTypeMapFor<Source, Destination>();
296+
map = ResolveTypeMap<Source, Destination>();
297297
map.PropertyMaps.First().Inline.ShouldBeFalse();
298-
map = FindTypeMapFor<Source1, Destination1>();
298+
map = ResolveTypeMap<Source1, Destination1>();
299299
map.PropertyMaps.First().Inline.ShouldBeFalse();
300-
map = FindTypeMapFor<Source2, Destination2>();
300+
map = ResolveTypeMap<Source2, Destination2>();
301301
map.PropertyMaps.First().Inline.ShouldBeFalse();
302-
map = FindTypeMapFor<Source3, Destination3>();
302+
map = ResolveTypeMap<Source3, Destination3>();
303303
map.PropertyMaps.First().Inline.ShouldBeFalse();
304-
map = FindTypeMapFor<Source4, Destination4>();
304+
map = ResolveTypeMap<Source4, Destination4>();
305305
map.PropertyMaps.First().Inline.ShouldBeFalse();
306-
map = FindTypeMapFor<Source5, Destination5>();
306+
map = ResolveTypeMap<Source5, Destination5>();
307307
map.PropertyMaps.First().Inline.ShouldBeFalse();
308308
}
309309
}
@@ -319,5 +319,5 @@ class Destination
319319
}
320320
protected override MapperConfiguration CreateConfiguration() => new(cfg => cfg.CreateMap<Source, Destination>());
321321
[Fact]
322-
public void Should_set_inline_accordingly() => FindTypeMapFor<Source, Destination>().PropertyMaps.First().Inline.ShouldBeFalse();
322+
public void Should_set_inline_accordingly() => ResolveTypeMap<Source, Destination>().PropertyMaps.First().Inline.ShouldBeFalse();
323323
}

0 commit comments

Comments
 (0)