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
24 changes: 24 additions & 0 deletions AgileMapper.UnitTests/Configuration/WhenIgnoringSourceMembers.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace AgileObjects.AgileMapper.UnitTests.Configuration
{
using Common;
using TestClasses;
#if !NET35
using Xunit;
#else
Expand All @@ -27,6 +28,29 @@ public void ShouldIgnoreAConfiguredSourceMember()
}
}

[Fact]
public void ShouldIgnoreAConfiguredSourceMemberConditionally()
{
using (var mapper = Mapper.CreateNew())
{
mapper.WhenMapping
.From<PublicField<int>>()
.ToANew<PublicField<string>>()
.If(ctx => ctx.Source.Value < 5)
.IgnoreSource(pf => pf.Value);

var matchingSource = new PublicField<int> { Value = 3 };
var matchingResult = mapper.Map(matchingSource).ToANew<PublicField<string>>();

matchingResult.Value.ShouldBeNull();

var nonMatchingSource = new PublicField<int> { Value = 7 };
var nonMatchingResult = mapper.Map(nonMatchingSource).ToANew<PublicField<string>>();

nonMatchingResult.Value.ShouldBe("7");
}
}

#region Helper Classes

private class IdTesterSource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,34 +276,37 @@ private MappingConfigContinuation<TSource, TTarget> RegisterNamedContructorParam

private static ParameterInfo GetUniqueConstructorParameterOrThrow<TParam>(string name = null)
{
var ignoreParameterType = typeof(TParam) == typeof(AnyParameterType);
var ignoreParameterName = name == null;
var settings = new
{
IgnoreParameterType = typeof(TParam) == typeof(AnyParameterType),
IgnoreParameterName = name == null
};

var matchingParameters = typeof(TTarget)
.GetPublicInstanceConstructors()
.Project(ctor => new
.Project(settings, (so, ctor) => new
{
Ctor = ctor,
MatchingParameters = ctor
.GetParameters()
.Filter(p =>
(ignoreParameterType || (p.ParameterType == typeof(TParam))) &&
(ignoreParameterName || (p.Name == name)))
.Filter(so, (si, p) =>
(si.IgnoreParameterType || (p.ParameterType == typeof(TParam))) &&
(si.IgnoreParameterName || (p.Name == name)))
.ToArray()
})
.Filter(d => d.MatchingParameters.Any())
.ToArray();

if (matchingParameters.Length == 0)
{
throw MissingParameterException(GetParameterMatchInfo<TParam>(name, !ignoreParameterType));
throw MissingParameterException(GetParameterMatchInfo<TParam>(name, !settings.IgnoreParameterType));
}

var matchingParameterData = matchingParameters.First();

if (matchingParameterData.MatchingParameters.Length > 1)
{
throw AmbiguousParameterException(GetParameterMatchInfo<TParam>(name, !ignoreParameterType));
throw AmbiguousParameterException(GetParameterMatchInfo<TParam>(name, !settings.IgnoreParameterType));
}

var matchingParameter = matchingParameterData.MatchingParameters.First();
Expand Down
2 changes: 1 addition & 1 deletion AgileMapper/Api/Configuration/EnumPairSpecifier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ private void ThrowIfAlreadyPaired<TPairedEnum>(TPairingEnum pairingEnumValue)
var pairingEnumValueName = pairingEnumValue.ToString();

var confictingPairing = relevantPairings
.FirstOrDefault(ep => ep.PairingEnumMemberName == pairingEnumValueName);
.FirstOrDefault(pairingEnumValueName, (pevn, ep) => ep.PairingEnumMemberName == pevn);

if (confictingPairing == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ private MapperConfigurationSpecifier ApplyConfigurationsIn(IEnumerable<Type> con

var orderedConfigurations = configurationIndexesByType
.OrderBy(kvp => kvp.Value)
.Project(kvp => configurationDataByType[kvp.Key].Configuration);
.Project(configurationDataByType, (cdbt, kvp) => cdbt[kvp.Key].Configuration);

Apply(orderedConfigurations);
return this;
Expand Down
4 changes: 2 additions & 2 deletions AgileMapper/Api/PlanTargetSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ public MappingPlanSet To<TTarget>(
_mapperContext
.RuleSets
.All
.Filter(ruleSet => ruleSet != _mapperContext.RuleSets.Project)
.Project(rs => GetMappingPlan(rs, configurations))
.Filter(_mapperContext, (mc, ruleSet) => ruleSet != mc.RuleSets.Project)
.Project(configurations, (cs, rs) => GetMappingPlan(rs, cs))
.ToArray());
}

Expand Down
6 changes: 3 additions & 3 deletions AgileMapper/Configuration/ConfiguredIgnoredSourceMember.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ namespace AgileObjects.AgileMapper.Configuration
using LinqExp = System.Linq.Expressions;
#else
using System.Linq.Expressions;
#endif
#if NET35
using Extensions.Internal;
#endif
using Members;

Expand All @@ -26,9 +29,6 @@ public ConfiguredIgnoredSourceMember(MappingConfigInfo configInfo, LambdaExpress
throw new MappingConfigurationException(failureReason);
}

public bool CouldApplyTo(IBasicMapperData mapperData)
=> RuleSetMatches(mapperData) && TypesAreCompatible(mapperData);

public override bool AppliesTo(IBasicMapperData mapperData)
{
return base.AppliesTo(mapperData) &&
Expand Down
11 changes: 9 additions & 2 deletions AgileMapper/Configuration/ConfiguredItemExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace AgileObjects.AgileMapper.Configuration
{
using System.Collections.Generic;
using System.Linq;
using Extensions;
using Extensions.Internal;
using Members;
Expand All @@ -10,13 +11,19 @@ internal static class ConfiguredItemExtensions
public static TItem FindMatch<TItem>(this IList<TItem> items, IBasicMapperData mapperData)
where TItem : UserConfiguredItemBase
{
return items?.FirstOrDefault(item => item.AppliesTo(mapperData));
return items?.FirstOrDefault(mapperData, (md, item) => item.AppliesTo(md));
}

public static IEnumerable<TItem> FindMatches<TItem>(this IEnumerable<TItem> items, IBasicMapperData mapperData)
where TItem : UserConfiguredItemBase
{
return items?.Filter(item => item.AppliesTo(mapperData)) ?? Enumerable<TItem>.Empty;
return items?.Filter(mapperData, (md, item) => item.AppliesTo(md)) ?? Enumerable<TItem>.Empty;
}

public static IList<TItem> FindPotentialMatches<TItem>(this IEnumerable<TItem> items, IBasicMapperData mapperData)
where TItem : UserConfiguredItemBase
{
return items?.Filter(mapperData, (md, item) => item.CouldApplyTo(md)).ToArray() ?? Enumerable<TItem>.EmptyArray;
}
}
}
2 changes: 1 addition & 1 deletion AgileMapper/Configuration/ConfiguredServiceProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public static IEnumerable<ConfiguredServiceProvider> CreateFromOrThrow<TServiceP
var providers = providerObject
.Type
.GetPublicInstanceMethods()
.Filter(method => Array.IndexOf(_serviceProviderMethodNames, method.Name) != -1)
.Filter(_serviceProviderMethodNames, (spmns, method) => Array.IndexOf(spmns, method.Name) != -1)
.Project(method => GetServiceProviderOrNull(
method,
providerObject,
Expand Down
10 changes: 5 additions & 5 deletions AgileMapper/Configuration/DerivedTypePairSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ private static void RemoveConflictingPairIfAppropriate(
return;
}

var existingTypePair = typePairs.FirstOrDefault(tp =>
!tp.HasConfiguredCondition && (tp.DerivedSourceType == typePair.DerivedSourceType));
var existingTypePair = typePairs.FirstOrDefault(typePair.DerivedSourceType, (dst, tp) =>
!tp.HasConfiguredCondition && (tp.DerivedSourceType == dst));

if (existingTypePair != null)
{
Expand All @@ -78,7 +78,7 @@ public IList<DerivedTypePair> GetImplementationTypePairsFor(
if (_typePairsByTargetType.TryGetValue(mapperData.TargetType, out var typePairs))
{
return typePairs
.Filter(tp => tp.IsImplementationPairing && tp.AppliesTo(mapperData))
.Filter(mapperData, (md, tp) => tp.IsImplementationPairing && tp.AppliesTo(md))
.ToArray();
}

Expand All @@ -98,7 +98,7 @@ public IList<DerivedTypePair> GetDerivedTypePairsFor(

if (_typePairsByTargetType.TryGetValue(mapperData.TargetType, out var typePairs))
{
return typePairs.Filter(tp => tp.AppliesTo(mapperData)).ToArray();
return typePairs.Filter(mapperData, (md, tp) => tp.AppliesTo(md)).ToArray();
}

return Enumerable<DerivedTypePair>.EmptyArray;
Expand Down Expand Up @@ -166,7 +166,7 @@ private void LookForDerivedTypePairs(ITypePair mapperData, MapperContext mapperC
foreach (var candidatePairData in candidatePairsData)
{
var derivedTargetType = derivedTargetTypes
.FirstOrDefault(t => t.Name == candidatePairData.DerivedTargetTypeName);
.FirstOrDefault(candidatePairData, (cpd, t) => t.Name == cpd.DerivedTargetTypeName);

if (derivedTargetType == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ private static void ThrowIfConflictingKeyPartFactoryExists<TKeyPartFactory>(
}

var conflictingFactory = existingFactories
.FirstOrDefault(kpf => kpf.ConflictsWith(factory));
.FirstOrDefault(factory, (f, kpf) => kpf.ConflictsWith(f));

if (conflictingFactory == null)
{
Expand Down
35 changes: 15 additions & 20 deletions AgileMapper/Configuration/UserConfigurationSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public MappedObjectCachingMode CacheMappedObjects(IBasicMapperData basicData)
}

var applicableSettings = _mappedObjectCachingSettings
.FirstOrDefault(tm => tm.AppliesTo(basicData));
.FirstOrDefault(basicData, (bd, tm) => tm.AppliesTo(bd));

if (applicableSettings == null)
{
Expand Down Expand Up @@ -135,7 +135,7 @@ public void Add(EntityKeyMappingSetting setting)
public bool MapEntityKeys(IBasicMapperData basicData)
{
var applicableSetting = _entityKeyMappingSettings?
.FirstOrDefault(s => s.AppliesTo(basicData))?
.FirstOrDefault(basicData, (bd, s) => s.AppliesTo(bd))?
.MapKeys;

return (applicableSetting == true) ||
Expand Down Expand Up @@ -199,7 +199,8 @@ private bool AutoDataSourceReversalEnabled<T>(T dataItem, Func<T, IBasicMapperDa

var basicData = mapperDataFactory.Invoke(dataItem);

return _dataSourceReversalSettings.FirstOrDefault(s => s.AppliesTo(basicData))?.Reverse == true;
return _dataSourceReversalSettings
.FirstOrDefault(basicData, (bd, s) => s.AppliesTo(bd))?.Reverse == true;
}

#endregion
Expand Down Expand Up @@ -322,8 +323,8 @@ public void Add(ConfiguredIgnoredMember ignoredMember)
IgnoredMembers.AddSortFilter(ignoredMember);
}

public ConfiguredIgnoredMember GetMemberIgnoreOrNull(IBasicMapperData mapperData)
=> _ignoredMembers.FindMatch(mapperData);
public IList<ConfiguredIgnoredMember> GetPotentialMemberIgnores(IBasicMapperData mapperData)
=> _ignoredMembers.FindPotentialMatches(mapperData);

#endregion

Expand Down Expand Up @@ -376,12 +377,12 @@ public void Add(ConfiguredDataSourceFactory dataSourceFactory)
}

public ConfiguredDataSourceFactory GetDataSourceFactoryFor(MappingConfigInfo configInfo)
=> _dataSourceFactories.First(dsf => dsf.ConfigInfo == configInfo);
=> _dataSourceFactories.First(configInfo, (ci, dsf) => dsf.ConfigInfo == ci);

public bool HasConfiguredToTargetDataSources { get; private set; }

public IList<IConfiguredDataSource> GetDataSources(IMemberMapperData mapperData)
=> GetDataSources(QueryDataSourceFactories(mapperData), mapperData);
public IList<ConfiguredDataSourceFactory> GetPotentialDataSourceFactories(IMemberMapperData mapperData)
=> _dataSourceFactories.FindPotentialMatches(mapperData);

public IList<IConfiguredDataSource> GetDataSourcesForToTarget(IMemberMapperData mapperData)
{
Expand All @@ -390,18 +391,12 @@ public IList<IConfiguredDataSource> GetDataSourcesForToTarget(IMemberMapperData
return Enumerable<IConfiguredDataSource>.EmptyArray;
}

var toTargetDataSourceFactories =
QueryDataSourceFactories(mapperData)
.Filter(dsf => dsf.TargetMember.IsRoot);
var toTargetDataSources = QueryDataSourceFactories(mapperData)
.Filter(dsf => dsf.TargetMember.IsRoot)
.Project(mapperData, (md, dsf) => dsf.Create(md))
.ToArray();

return GetDataSources(toTargetDataSourceFactories, mapperData);
}

private static IList<IConfiguredDataSource> GetDataSources(
IEnumerable<ConfiguredDataSourceFactory> factories,
IMemberMapperData mapperData)
{
return factories.Project(dsf => dsf.Create(mapperData)).ToArray();
return toTargetDataSources;
}

public IEnumerable<ConfiguredDataSourceFactory> QueryDataSourceFactories(IBasicMapperData mapperData)
Expand Down Expand Up @@ -541,7 +536,7 @@ private static void ThrowIfConflictingItemExists<TConfiguredItem, TExistingItem>
where TExistingItem : UserConfiguredItemBase
{
var conflictingItem = existingItems?
.FirstOrDefault(ci => ci.ConflictsWith(configuredItem));
.FirstOrDefault(configuredItem, (sci, ci) => ci.ConflictsWith(sci));

if (conflictingItem == null)
{
Expand Down
5 changes: 4 additions & 1 deletion AgileMapper/Configuration/UserConfiguredItemBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ public Expression GetConditionOrNull(IMemberMapperData mapperData)
protected virtual Expression GetConditionOrNull(IMemberMapperData mapperData, CallbackPosition position)
=> ConfigInfo.GetConditionOrNull(mapperData, position, TargetMember);

public bool CouldApplyTo(IBasicMapperData mapperData)
=> RuleSetMatches(mapperData) && TypesMatch(mapperData);

public virtual bool AppliesTo(IBasicMapperData mapperData)
{
return RuleSetMatches(mapperData) &&
Expand All @@ -101,7 +104,7 @@ public virtual bool AppliesTo(IBasicMapperData mapperData)
TypesMatch(mapperData);
}

protected bool RuleSetMatches(IBasicMapperData mapperData) => ConfigInfo.IsFor(mapperData.RuleSet);
private bool RuleSetMatches(IBasicMapperData mapperData) => ConfigInfo.IsFor(mapperData.RuleSet);

private bool TargetMembersMatch(IBasicMapperData mapperData)
{
Expand Down
2 changes: 1 addition & 1 deletion AgileMapper/DataSources/DataSourceBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ private static bool IsNotOptionalEntityMemberId(IMemberMapperData mapperData)
.Instance
.MemberCache
.GetTargetMembers(mapperData.TargetType)
.FirstOrDefault(m => m.Name == entityMemberName);
.FirstOrDefault(entityMemberName, (emn, m) => m.Name == emn);

return !mapperData.IsEntity(entityMember?.Type, out _);
}
Expand Down
4 changes: 2 additions & 2 deletions AgileMapper/DataSources/EnumerableDataSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ private static bool IsNotMappingFromLinkingType(
.GetSourceMembers(sourceElementType);

var backLinkMember = sourceElementMembers
.FirstOrDefault(m => m.IsComplex && m.Type == mapperData.SourceType);
.FirstOrDefault(mapperData.SourceType, (st, m) => m.IsComplex && m.Type == st);

if (backLinkMember == null)
{
Expand All @@ -100,7 +100,7 @@ private static bool IsNotMappingFromLinkingType(
}

var otherComplexTypeMembers = sourceElementMembers
.Filter(m => m.IsComplex && (m.Type != mapperData.SourceType))
.Filter(mapperData, (md, m) => m.IsComplex && (m.Type != md.SourceType))
.ToArray();

if ((otherComplexTypeMembers.Length != 1) ||
Expand Down
Loading