Skip to content

Commit 931b2e4

Browse files
authored
Auto-apply ApplyAfter configs, re: #91 (#95)
* Adding failing test * Automatically applying configurations specified in ApplyAfter attributes
1 parent 884abff commit 931b2e4

File tree

3 files changed

+45
-34
lines changed

3 files changed

+45
-34
lines changed

AgileMapper.UnitTests/Configuration/WhenApplyingMapperConfigurations.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,33 @@ public void ShouldApplyMapperConfigurationsInOrder()
175175
}
176176
}
177177

178+
// See https://github.com/agileobjects/AgileMapper/issues/91
179+
[Fact]
180+
public void ShouldApplyMapperConfigurationsInOrderAutomatically()
181+
{
182+
var values = new List<int> { 1, 2, 3 };
183+
var provider = new StubServiceProvider(values);
184+
185+
var grandParent = new GrandParent
186+
{
187+
DatChild = new Parent { MyChild = new Child() }
188+
};
189+
190+
using (var mapper = Mapper.CreateNew())
191+
{
192+
mapper.WhenMapping
193+
.UseServiceProvider(provider)
194+
.UseConfigurations
195+
.From<GrandParentMapperConfiguration>();
196+
197+
var result = mapper.Map(grandParent).ToANew<GrandParentDto>();
198+
199+
result.MyChild.ShouldNotBeNull();
200+
result.MyChild.MyChild.ShouldNotBeNull();
201+
result.MyChild.MyChild.IsMyCountGtrZero.ShouldBeTrue();
202+
}
203+
}
204+
178205
#region Helper Classes
179206

180207
public class PfiToPfsMapperConfiguration : MapperConfiguration

AgileMapper.UnitTests/Configuration/WhenApplyingMapperConfigurationsIncorrectly.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,19 +75,20 @@ public void ShouldErrorIfDuplicateConfigurationAdded()
7575
}
7676

7777
[Fact]
78-
public void ShouldErrorIfDependentConfigurationAddedBeforeDependedOnConfiguration()
78+
public void ShouldErrorIfRedundantConfigurationAdded()
7979
{
8080
var configEx = Should.Throw<MappingConfigurationException>(() =>
8181
{
8282
using (var mapper = Mapper.CreateNew())
8383
{
8484
mapper.WhenMapping.UseConfigurations
85-
.From<WhenApplyingMapperConfigurations.ParentMapperConfiguration>();
85+
.From<WhenApplyingMapperConfigurations.ParentMapperConfiguration>()
86+
.From<WhenApplyingMapperConfigurations.ChildMapperConfiguration>();
8687
}
8788
});
8889

89-
configEx.Message.ShouldContain("ParentMapperConfiguration");
9090
configEx.Message.ShouldContain("ChildMapperConfiguration");
91+
configEx.Message.ShouldContain("already been applied");
9192
}
9293

9394
[Fact]

AgileMapper/Api/Configuration/MapperConfigurationSpecifier.cs

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ public MapperConfigurationSpecifier From(IEnumerable<Assembly> assemblies, Func<
8484

8585
ThrowIfInvalidAssembliesSupplied(matchingAssemblies.Any(), nullSupplied: false);
8686

87-
ApplyConfigurationsIn(matchingAssemblies.SelectMany(QueryConfigurationTypesIn));
88-
return this;
87+
return ApplyConfigurationsIn(matchingAssemblies.SelectMany(QueryConfigurationTypesIn));
8988
}
9089

9190
/// <summary>
@@ -101,12 +100,10 @@ public MapperConfigurationSpecifier From<TConfiguration>()
101100
where TConfiguration : MapperConfiguration, new()
102101
{
103102
ThrowIfConfigurationAlreadyApplied(typeof(TConfiguration));
104-
ThrowIfDependedOnConfigurationNotApplied(typeof(TConfiguration));
105103

106-
var configuration = new TConfiguration();
104+
var configurationTypeChain = GetAllConfigurationTypesFor(typeof(TConfiguration));
107105

108-
Apply(configuration);
109-
return this;
106+
return ApplyConfigurationsIn(configurationTypeChain);
110107
}
111108

112109
private void ThrowIfConfigurationAlreadyApplied(Type configurationType)
@@ -118,29 +115,17 @@ private void ThrowIfConfigurationAlreadyApplied(Type configurationType)
118115
}
119116
}
120117

121-
private void ThrowIfDependedOnConfigurationNotApplied(Type configurationType)
118+
private static IEnumerable<Type> GetAllConfigurationTypesFor(Type configurationType)
122119
{
123-
var dependedOnTypes = GetDependedOnConfigurationTypesFor(configurationType);
124-
125-
if (dependedOnTypes.None())
126-
{
127-
return;
128-
}
129-
130-
var missingDependencies = dependedOnTypes
131-
.Filter(t => !ConfigurationApplied(t))
132-
.ToArray();
133-
134-
if (missingDependencies.None())
120+
foreach (var dependedOnType in GetDependedOnConfigurationTypesFor(configurationType))
135121
{
136-
return;
122+
foreach (var nestedDependedOnType in GetAllConfigurationTypesFor(dependedOnType))
123+
{
124+
yield return nestedDependedOnType;
125+
}
137126
}
138127

139-
var configurationTypeName = configurationType.GetFriendlyName();
140-
var dependencyNames = missingDependencies.Project(d => d.GetFriendlyName()).Join(", ");
141-
142-
throw new MappingConfigurationException(
143-
$"Configuration {configurationTypeName} must be registered after depended-on configuration(s) {dependencyNames}");
128+
yield return configurationType;
144129
}
145130

146131
private bool ConfigurationApplied(Type configurationType)
@@ -158,12 +143,9 @@ private bool ConfigurationApplied(Type configurationType)
158143
/// to be registered.
159144
/// </returns>
160145
public MapperConfigurationSpecifier FromAssemblyOf<T>()
161-
{
162-
ApplyConfigurationsIn(QueryConfigurationTypesIn(typeof(T).GetAssembly()));
163-
return this;
164-
}
146+
=> ApplyConfigurationsIn(QueryConfigurationTypesIn(typeof(T).GetAssembly()));
165147

166-
private void ApplyConfigurationsIn(IEnumerable<Type> configurationTypes)
148+
private MapperConfigurationSpecifier ApplyConfigurationsIn(IEnumerable<Type> configurationTypes)
167149
{
168150
var configurationData = configurationTypes
169151
.Select(t => new ConfigurationData(t))
@@ -172,7 +154,7 @@ private void ApplyConfigurationsIn(IEnumerable<Type> configurationTypes)
172154
if (configurationData.None(d => d.DependedOnConfigurationTypes.Any()))
173155
{
174156
Apply(configurationData.Project(d => d.Configuration));
175-
return;
157+
return this;
176158
}
177159

178160
var configurationCount = configurationData.Count;
@@ -213,6 +195,7 @@ private void ApplyConfigurationsIn(IEnumerable<Type> configurationTypes)
213195
.Project(kvp => configurationDataByType[kvp.Key].Configuration);
214196

215197
Apply(orderedConfigurations);
198+
return this;
216199
}
217200

218201
private static void InsertWithOrder(

0 commit comments

Comments
 (0)