diff --git a/AgileMapper.UnitTests.MoreTestClasses/AgileMapper.UnitTests.MoreTestClasses.csproj b/AgileMapper.UnitTests.MoreTestClasses/AgileMapper.UnitTests.MoreTestClasses.csproj index ef63b0656..1aea32035 100644 --- a/AgileMapper.UnitTests.MoreTestClasses/AgileMapper.UnitTests.MoreTestClasses.csproj +++ b/AgileMapper.UnitTests.MoreTestClasses/AgileMapper.UnitTests.MoreTestClasses.csproj @@ -5,6 +5,7 @@ net35;netstandard1.0 AgileObjects.AgileMapper.UnitTests.MoreTestClasses AgileObjects.AgileMapper.UnitTests.MoreTestClasses + false diff --git a/AgileMapper.UnitTests.NetCore/AgileMapper.UnitTests.NetCore.csproj b/AgileMapper.UnitTests.NetCore/AgileMapper.UnitTests.NetCore.csproj index 102f71ace..2af4e7c7b 100644 --- a/AgileMapper.UnitTests.NetCore/AgileMapper.UnitTests.NetCore.csproj +++ b/AgileMapper.UnitTests.NetCore/AgileMapper.UnitTests.NetCore.csproj @@ -5,7 +5,6 @@ netcoreapp1.0 true AgileObjects.AgileMapper.UnitTests.NetCore - AgileObjects.AgileMapper.UnitTests.NetCore true 1.1.9 false @@ -14,6 +13,7 @@ false false AgileObjects.AgileMapper.UnitTests.NetCore + false @@ -25,10 +25,10 @@ - + all @@ -48,6 +48,10 @@ + + + + diff --git a/AgileMapper.UnitTests.NetCore2.1/AgileMapper.UnitTests.NetCore2.1.csproj b/AgileMapper.UnitTests.NetCore2.1/AgileMapper.UnitTests.NetCore2.1.csproj index d6d85e595..0d223b776 100644 --- a/AgileMapper.UnitTests.NetCore2.1/AgileMapper.UnitTests.NetCore2.1.csproj +++ b/AgileMapper.UnitTests.NetCore2.1/AgileMapper.UnitTests.NetCore2.1.csproj @@ -5,7 +5,6 @@ netcoreapp2.1 true AgileObjects.AgileMapper.UnitTests.NetCore2_1 - AgileObjects.AgileMapper.UnitTests.NetCore2_1 true 2.1.2 false @@ -14,25 +13,23 @@ false false AgileObjects.AgileMapper.UnitTests.NetCore2 + false - TRACE;DEBUG;NETCOREAPP2_0;NET_STANDARD + TRACE;DEBUG;NET_STANDARD;FEATURE_STRINGSPLIT_OPTIONS; - TRACE;RELEASE;NETCOREAPP2_0;NETCOREAPP2_1;NET_STANDARD + TRACE;RELEASE;NET_STANDARD;FEATURE_STRINGSPLIT_OPTIONS; - - - - + all diff --git a/AgileMapper.UnitTests.NetCore2.2/AgileMapper.UnitTests.NetCore2.2.csproj b/AgileMapper.UnitTests.NetCore2.2/AgileMapper.UnitTests.NetCore2.2.csproj index 170bb8528..be9a285f6 100644 --- a/AgileMapper.UnitTests.NetCore2.2/AgileMapper.UnitTests.NetCore2.2.csproj +++ b/AgileMapper.UnitTests.NetCore2.2/AgileMapper.UnitTests.NetCore2.2.csproj @@ -4,8 +4,7 @@ netcoreapp2.2 true - AgileObjects.AgileMapper.UnitTests.NetCore2_1 - AgileObjects.AgileMapper.UnitTests.NetCore2_1 + AgileObjects.AgileMapper.UnitTests.NetCore2_2 true 2.2.2 false @@ -14,25 +13,23 @@ false false AgileObjects.AgileMapper.UnitTests.NetCore2 + false - TRACE;DEBUG;NETCOREAPP2_0;NET_STANDARD + TRACE;DEBUG;NET_STANDARD;FEATURE_STRINGSPLIT_OPTIONS; - TRACE;RELEASE;NETCOREAPP2_0;NET_STANDARD + TRACE;RELEASE;NET_STANDARD;FEATURE_STRINGSPLIT_OPTIONS; - - - - + all diff --git a/AgileMapper.UnitTests.NetCore2/AgileMapper.UnitTests.NetCore2.csproj b/AgileMapper.UnitTests.NetCore2/AgileMapper.UnitTests.NetCore2.csproj index 81b87e1d9..491bc905d 100644 --- a/AgileMapper.UnitTests.NetCore2/AgileMapper.UnitTests.NetCore2.csproj +++ b/AgileMapper.UnitTests.NetCore2/AgileMapper.UnitTests.NetCore2.csproj @@ -5,7 +5,6 @@ netcoreapp2.0 true AgileObjects.AgileMapper.UnitTests.NetCore2 - AgileObjects.AgileMapper.UnitTests.NetCore2 true 2.0.7 false @@ -14,25 +13,23 @@ false false AgileObjects.AgileMapper.UnitTests.NetCore2 + false - TRACE;DEBUG;NETCOREAPP2_0;NET_STANDARD + TRACE;DEBUG;NET_STANDARD;FEATURE_STRINGSPLIT_OPTIONS; - TRACE;RELEASE;NETCOREAPP2_0;NET_STANDARD + TRACE;RELEASE;NET_STANDARD;FEATURE_STRINGSPLIT_OPTIONS; - - - - + all diff --git a/AgileMapper.UnitTests.NetCore3/AgileMapper.UnitTests.NetCore3.csproj b/AgileMapper.UnitTests.NetCore3/AgileMapper.UnitTests.NetCore3.csproj new file mode 100644 index 000000000..a2046381a --- /dev/null +++ b/AgileMapper.UnitTests.NetCore3/AgileMapper.UnitTests.NetCore3.csproj @@ -0,0 +1,60 @@ + + + + + netcoreapp3.0 + true + AgileObjects.AgileMapper.UnitTests.NetCore3 + true + 3.0.0 + false + false + false + false + false + AgileObjects.AgileMapper.UnitTests.NetCore2 + false + + + + TRACE;DEBUG;NET_STANDARD;FEATURE_STRINGSPLIT_OPTIONS; + + + + TRACE;RELEASE;NET_STANDARD;FEATURE_STRINGSPLIT_OPTIONS; + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + + + + %(RecursiveDir)%(Filename)%(Extension) + + + + + + + + + + + + diff --git a/AgileMapper.UnitTests.Orms.EFCore2.NetCore2/AgileMapper.UnitTests.Orms.EfCore2.NetCore2.csproj b/AgileMapper.UnitTests.Orms.EFCore2.NetCore2/AgileMapper.UnitTests.Orms.EfCore2.NetCore2.csproj index e2f6d12c9..2afc1026f 100644 --- a/AgileMapper.UnitTests.Orms.EFCore2.NetCore2/AgileMapper.UnitTests.Orms.EfCore2.NetCore2.csproj +++ b/AgileMapper.UnitTests.Orms.EFCore2.NetCore2/AgileMapper.UnitTests.Orms.EfCore2.NetCore2.csproj @@ -5,7 +5,6 @@ netcoreapp2.0 true AgileObjects.AgileMapper.UnitTests.Orms.EfCore2.NetCore2 - AgileObjects.AgileMapper.UnitTests.Orms.EfCore2.NetCore2 true 2.0.7 false @@ -16,6 +15,7 @@ false false AgileObjects.AgileMapper.UnitTests.Orms.EfCore2.NetCore2 + false diff --git a/AgileMapper.UnitTests/AgileMapper.UnitTests.csproj b/AgileMapper.UnitTests/AgileMapper.UnitTests.csproj index ef3d3d7fe..a566dfa84 100644 --- a/AgileMapper.UnitTests/AgileMapper.UnitTests.csproj +++ b/AgileMapper.UnitTests/AgileMapper.UnitTests.csproj @@ -232,6 +232,7 @@ + diff --git a/AgileMapper.UnitTests/Configuration/WhenConfiguringDataSources.cs b/AgileMapper.UnitTests/Configuration/WhenConfiguringDataSources.cs index 493e4fe17..11c4436f3 100644 --- a/AgileMapper.UnitTests/Configuration/WhenConfiguringDataSources.cs +++ b/AgileMapper.UnitTests/Configuration/WhenConfiguringDataSources.cs @@ -574,7 +574,7 @@ public void ShouldApplyAConfiguredExpressionToAnArray() mapper.WhenMapping .From>() .To>() -#if NETCOREAPP2_0 +#if FEATURE_STRINGSPLIT_OPTIONS .Map(ctx => ctx.Source.Value.Split(':', StringSplitOptions.None)) #else .Map(ctx => ctx.Source.Value.Split(':')) @@ -1244,7 +1244,9 @@ public void ShouldApplyAConfiguredSourceInterfaceMember() result.Name.ShouldBe("input"); result.Info.ShouldNotBeNull(); result.Info.Id.ShouldBe("12321"); - result.Info.Value.ShouldNotBeNull(); + + // Source has a .Value member, but we don't runtime-type interfaces + result.Info.Value.ShouldBeNull(); } } diff --git a/AgileMapper.UnitTests/TestClasses/IPublicInterface.cs b/AgileMapper.UnitTests/TestClasses/IPublicInterface.cs index 553b0727d..4c2f5c898 100644 --- a/AgileMapper.UnitTests/TestClasses/IPublicInterface.cs +++ b/AgileMapper.UnitTests/TestClasses/IPublicInterface.cs @@ -4,4 +4,9 @@ public interface IPublicInterface { T Value { get; set; } } + + public interface IPublicInterface + { + object Value { get; set; } + } } \ No newline at end of file diff --git a/AgileMapper.UnitTests/TestClasses/PublicImplementation.cs b/AgileMapper.UnitTests/TestClasses/PublicImplementation.cs index 9e68616c7..2f5efd6ce 100644 --- a/AgileMapper.UnitTests/TestClasses/PublicImplementation.cs +++ b/AgileMapper.UnitTests/TestClasses/PublicImplementation.cs @@ -1,7 +1,9 @@ namespace AgileObjects.AgileMapper.UnitTests.TestClasses { - public class PublicImplementation : IPublicInterface + public class PublicImplementation : IPublicInterface, IPublicInterface { public T Value { get; set; } + + object IPublicInterface.Value { get => Value; set => Value = (T)value; } } } \ No newline at end of file diff --git a/AgileMapper.UnitTests/TestClasses/PublicOtherImplementation.cs b/AgileMapper.UnitTests/TestClasses/PublicOtherImplementation.cs new file mode 100644 index 000000000..141fe48b7 --- /dev/null +++ b/AgileMapper.UnitTests/TestClasses/PublicOtherImplementation.cs @@ -0,0 +1,9 @@ +namespace AgileObjects.AgileMapper.UnitTests.TestClasses +{ + public class PublicOtherImplementation : IPublicInterface, IPublicInterface + { + public T Value { get; set; } + + object IPublicInterface.Value { get => Value; set => Value = (T)value; } + } +} \ No newline at end of file diff --git a/AgileMapper.UnitTests/WhenMappingToNewComplexTypeMembers.cs b/AgileMapper.UnitTests/WhenMappingToNewComplexTypeMembers.cs index 979889b96..318ed6c53 100644 --- a/AgileMapper.UnitTests/WhenMappingToNewComplexTypeMembers.cs +++ b/AgileMapper.UnitTests/WhenMappingToNewComplexTypeMembers.cs @@ -204,6 +204,15 @@ public void ShouldMapASourcePropertyToMultipleTargets() result.CurrencyId.ShouldBe(1); } + [Fact] + public void ShouldMapANonGenericInterfaceMember() + { + var source = new PublicField(); + var result = Mapper.Map(source).ToANew>(); + + result.ShouldNotBeNull(); + } + // See https://github.com/agileobjects/AgileMapper/issues/146 [Fact] public void ShouldMapToATargetInterfaceMembersImplementedInterfaceMembers() diff --git a/AgileMapper.UnitTests/WhenMappingToNewEnumerableMembers.cs b/AgileMapper.UnitTests/WhenMappingToNewEnumerableMembers.cs index a9aa4f14d..fbf214681 100644 --- a/AgileMapper.UnitTests/WhenMappingToNewEnumerableMembers.cs +++ b/AgileMapper.UnitTests/WhenMappingToNewEnumerableMembers.cs @@ -283,7 +283,7 @@ public void ShouldHandleANullSourceMemberInAConfiguredEnumerableSource() mapper.WhenMapping .From>() .To>() -#if NETCOREAPP2_0 +#if FEATURE_STRINGSPLIT_OPTIONS .Map(ctx => ctx.Source.Value.Split(':', System.StringSplitOptions.None)) #else .Map(ctx => ctx.Source.Value.Split(':')) diff --git a/AgileMapper.sln b/AgileMapper.sln index 92b8aba16..d15ae4af6 100644 --- a/AgileMapper.sln +++ b/AgileMapper.sln @@ -61,6 +61,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Performance", "Performance" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Orms", "Orms", "{86B68C08-267A-47BD-BCBC-427710D2654F}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AgileMapper.UnitTests.NetCore3", "AgileMapper.UnitTests.NetCore3\AgileMapper.UnitTests.NetCore3.csproj", "{A6A0E6FF-E114-4F26-99E9-CAD1C03BD743}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -151,6 +153,10 @@ Global {D1AB8AB2-CFF5-4AB0-8D06-3ADAD78D6B43}.Debug|Any CPU.Build.0 = Debug|Any CPU {D1AB8AB2-CFF5-4AB0-8D06-3ADAD78D6B43}.Release|Any CPU.ActiveCfg = Release|Any CPU {D1AB8AB2-CFF5-4AB0-8D06-3ADAD78D6B43}.Release|Any CPU.Build.0 = Release|Any CPU + {A6A0E6FF-E114-4F26-99E9-CAD1C03BD743}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A6A0E6FF-E114-4F26-99E9-CAD1C03BD743}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A6A0E6FF-E114-4F26-99E9-CAD1C03BD743}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A6A0E6FF-E114-4F26-99E9-CAD1C03BD743}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -178,6 +184,7 @@ Global {D1AB8AB2-CFF5-4AB0-8D06-3ADAD78D6B43} = {88D48136-E176-4AF7-ACA4-A2954F3BD55B} {8155DEC6-431B-4371-9EBC-D8E729AF3096} = {88D48136-E176-4AF7-ACA4-A2954F3BD55B} {86B68C08-267A-47BD-BCBC-427710D2654F} = {88D48136-E176-4AF7-ACA4-A2954F3BD55B} + {A6A0E6FF-E114-4F26-99E9-CAD1C03BD743} = {88D48136-E176-4AF7-ACA4-A2954F3BD55B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C39E9BDB-0077-445C-8F09-801CAE1AF8AB} diff --git a/AgileMapper.sln.DotSettings b/AgileMapper.sln.DotSettings index 5a03b1850..ec676422d 100644 --- a/AgileMapper.sln.DotSettings +++ b/AgileMapper.sln.DotSettings @@ -1,4 +1,5 @@  + HINT True <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /> <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /> diff --git a/AgileMapper/Api/Configuration/DerivedPairTargetTypeSpecifier.cs b/AgileMapper/Api/Configuration/DerivedPairTargetTypeSpecifier.cs index b68318d80..c4d2bf244 100644 --- a/AgileMapper/Api/Configuration/DerivedPairTargetTypeSpecifier.cs +++ b/AgileMapper/Api/Configuration/DerivedPairTargetTypeSpecifier.cs @@ -58,7 +58,7 @@ private void ThrowIfUnconstructable() var configuredImplementationPairings = MapperContext .UserConfigurations .DerivedTypes - .GetImplementationTypePairsFor(_configInfo.ToMapperData(), MapperContext); + .GetImplementationTypePairsFor(_configInfo.ToMapperData()); if (configuredImplementationPairings.None()) { diff --git a/AgileMapper/Configuration/DataSourceReversalSetting.cs b/AgileMapper/Configuration/DataSourceReversalSetting.cs index 36176ce70..3b2aa1c9c 100644 --- a/AgileMapper/Configuration/DataSourceReversalSetting.cs +++ b/AgileMapper/Configuration/DataSourceReversalSetting.cs @@ -4,7 +4,6 @@ namespace AgileObjects.AgileMapper.Configuration using System; #endif using Members; - using ReadableExpressions.Extensions; internal class DataSourceReversalSetting : UserConfiguredItemBase @@ -48,15 +47,12 @@ public string GetConflictMessage(DataSourceReversalSetting conflicting) return GetRedundantSettingConflictMessage(conflicting, " by default"); } - var targetType = ConfigInfo.TargetType.GetFriendlyName(); - if (ConfigInfo.IsForAllSourceTypes()) { - return GetRedundantSettingConflictMessage(conflicting, " when mapping to " + targetType); + return GetRedundantSettingConflictMessage(conflicting, " when mapping to " + TargetTypeName); } - var sourceType = ConfigInfo.SourceType.GetFriendlyName(); - var typeSettings = $" when mapping {sourceType} -> {targetType}"; + var typeSettings = $" when mapping {SourceTypeName} -> {TargetTypeName}"; return GetRedundantSettingConflictMessage(conflicting, typeSettings); } diff --git a/AgileMapper/Configuration/DerivedTypePair.cs b/AgileMapper/Configuration/DerivedTypePair.cs index 8bd00ba1d..c87d87941 100644 --- a/AgileMapper/Configuration/DerivedTypePair.cs +++ b/AgileMapper/Configuration/DerivedTypePair.cs @@ -12,6 +12,8 @@ internal class DerivedTypePair : UserConfiguredItemBase, IComparable { + private readonly bool _isInterfacePairing; + public DerivedTypePair( MappingConfigInfo configInfo, Type derivedSourceType, @@ -19,6 +21,7 @@ public DerivedTypePair( : base(configInfo) { IsImplementationPairing = configInfo.TargetType.IsAbstract(); + _isInterfacePairing = IsImplementationPairing && configInfo.TargetType.IsInterface(); DerivedSourceType = derivedSourceType; DerivedTargetType = derivedTargetType; } @@ -89,7 +92,21 @@ private static void ThrowIfPairingIsUnnecessary( public Type DerivedTargetType { get; } public override bool AppliesTo(IBasicMapperData mapperData) - => mapperData.SourceType.IsAssignableTo(DerivedSourceType) && base.AppliesTo(mapperData); + { + if (!base.AppliesTo(mapperData)) + { + return false; + } + + if (mapperData.SourceType.IsAssignableTo(DerivedSourceType)) + { + return true; + } + + return _isInterfacePairing && + mapperData.SourceType.IsAssignableTo(SourceType) && + mapperData.TargetType.IsAssignableTo(TargetType); + } int IComparable.CompareTo(DerivedTypePair other) { @@ -114,7 +131,7 @@ int IComparable.CompareTo(DerivedTypePair other) [ExcludeFromCodeCoverage] public override string ToString() { - var rootSourceType = ConfigInfo.SourceType.GetFriendlyName(); + var rootSourceType = SourceTypeName; var rootTargetType = TargetTypeName; var derivedSourceType = DerivedSourceType.GetFriendlyName(); var derivedTargetType = DerivedTargetType.GetFriendlyName(); diff --git a/AgileMapper/Configuration/DerivedTypePairSet.cs b/AgileMapper/Configuration/DerivedTypePairSet.cs index 339e9fa20..f6ebcb063 100644 --- a/AgileMapper/Configuration/DerivedTypePairSet.cs +++ b/AgileMapper/Configuration/DerivedTypePairSet.cs @@ -28,7 +28,7 @@ public void Add(DerivedTypePair typePair) { if (typePair.IsImplementationPairing) { - AddTypePairFor(typePair.ConfigInfo.TargetType, typePair); + AddTypePairFor(typePair.TargetType, typePair); return; } @@ -71,9 +71,7 @@ private static void RemoveConflictingPairIfAppropriate( } } - public IList GetImplementationTypePairsFor( - IBasicMapperData mapperData, - MapperContext mapperContext) + public IList GetImplementationTypePairsFor(IBasicMapperData mapperData) { if (_typePairsByTargetType.TryGetValue(mapperData.TargetType, out var typePairs)) { @@ -306,6 +304,7 @@ private static bool SkipDerivedTypePairsLookup( out Func derivedTargetTypeNameFactory) { if (rootSourceType.IsSealed() || rootTargetType.IsSealed() || + rootSourceType.IsInterface() || rootTargetType.IsInterface() || rootSourceType.IsFromBcl() || rootTargetType.IsFromBcl()) { derivedTargetTypeNameFactory = null; diff --git a/AgileMapper/Configuration/Dictionaries/DictionaryKeyPartFactoryBase.cs b/AgileMapper/Configuration/Dictionaries/DictionaryKeyPartFactoryBase.cs index 7574364eb..4e0974fd0 100644 --- a/AgileMapper/Configuration/Dictionaries/DictionaryKeyPartFactoryBase.cs +++ b/AgileMapper/Configuration/Dictionaries/DictionaryKeyPartFactoryBase.cs @@ -1,10 +1,7 @@ namespace AgileObjects.AgileMapper.Configuration.Dictionaries { - using ReadableExpressions.Extensions; - internal abstract class DictionaryKeyPartFactoryBase : UserConfiguredItemBase { - protected DictionaryKeyPartFactoryBase(MappingConfigInfo configInfo) : base(configInfo) { @@ -16,6 +13,6 @@ protected DictionaryKeyPartFactoryBase(MappingConfigInfo configInfo) public abstract string GetConflictMessage(); protected string TargetScopeDescription - => IsForAllTargetTypes ? "globally" : "for target type " + ConfigInfo.TargetType.GetFriendlyName(); + => IsForAllTargetTypes ? "globally" : "for target type " + TargetTypeName; } } \ No newline at end of file diff --git a/AgileMapper/Configuration/Dictionaries/DictionarySettings.cs b/AgileMapper/Configuration/Dictionaries/DictionarySettings.cs index 20390bf7d..2fc72e2e6 100644 --- a/AgileMapper/Configuration/Dictionaries/DictionarySettings.cs +++ b/AgileMapper/Configuration/Dictionaries/DictionarySettings.cs @@ -52,7 +52,7 @@ public void AddFullKey(CustomDictionaryKey configuredKey) return; } - var targetDictionaryTypes = configuredKey.ConfigInfo.TargetType.GetDictionaryTypes(); + var targetDictionaryTypes = configuredKey.TargetType.GetDictionaryTypes(); if (!targetDictionaryTypes.Value.IsSimple()) { diff --git a/AgileMapper/Configuration/Dictionaries/ElementKeyPartFactory.cs b/AgileMapper/Configuration/Dictionaries/ElementKeyPartFactory.cs index 6ec24cc35..f516ad159 100644 --- a/AgileMapper/Configuration/Dictionaries/ElementKeyPartFactory.cs +++ b/AgileMapper/Configuration/Dictionaries/ElementKeyPartFactory.cs @@ -180,9 +180,9 @@ public override string ToString() { var sourceType = ConfigInfo.IsForAllSourceTypes() ? "All sources" - : ConfigInfo.SourceType.GetFriendlyName(); + : SourceTypeName; - var targetTypeName = ConfigInfo.TargetType == typeof(object) + var targetTypeName = TargetType == typeof(object) ? "All targets" : TargetTypeName; diff --git a/AgileMapper/Configuration/Dictionaries/JoiningNameFactory.cs b/AgileMapper/Configuration/Dictionaries/JoiningNameFactory.cs index e2ca54dcd..aafac7220 100644 --- a/AgileMapper/Configuration/Dictionaries/JoiningNameFactory.cs +++ b/AgileMapper/Configuration/Dictionaries/JoiningNameFactory.cs @@ -239,9 +239,9 @@ public override string ToString() { var sourceType = ConfigInfo.IsForAllSourceTypes() ? "All sources" - : ConfigInfo.SourceType.GetFriendlyName(); + : SourceType.GetFriendlyName(); - var targetTypeName = ConfigInfo.TargetType == typeof(object) + var targetTypeName = TargetType == typeof(object) ? "All targets" : TargetTypeName; diff --git a/AgileMapper/Configuration/EntityKeyMappingSetting.cs b/AgileMapper/Configuration/EntityKeyMappingSetting.cs index ae0764e34..f872250d3 100644 --- a/AgileMapper/Configuration/EntityKeyMappingSetting.cs +++ b/AgileMapper/Configuration/EntityKeyMappingSetting.cs @@ -4,7 +4,6 @@ namespace AgileObjects.AgileMapper.Configuration using System; #endif using Members; - using ReadableExpressions.Extensions; internal class EntityKeyMappingSetting : UserConfiguredItemBase @@ -44,15 +43,12 @@ public override bool ConflictsWith(UserConfiguredItemBase otherItem) public string GetConflictMessage(EntityKeyMappingSetting conflicting) { - var targetType = ConfigInfo.TargetType.GetFriendlyName(); - if (ConfigInfo.IsForAllSourceTypes()) { - return GetRedundantSettingConflictMessage(conflicting, " when mapping to " + targetType); + return GetRedundantSettingConflictMessage(conflicting, " when mapping to " + TargetTypeName); } - var sourceType = ConfigInfo.SourceType.GetFriendlyName(); - var typeSettings = $" when mapping {sourceType} -> {targetType}"; + var typeSettings = $" when mapping {SourceTypeName} -> {TargetTypeName}"; return GetRedundantSettingConflictMessage(conflicting, typeSettings); } diff --git a/AgileMapper/Configuration/MappedObjectCachingSetting.cs b/AgileMapper/Configuration/MappedObjectCachingSetting.cs index b45ac678e..156fe207c 100644 --- a/AgileMapper/Configuration/MappedObjectCachingSetting.cs +++ b/AgileMapper/Configuration/MappedObjectCachingSetting.cs @@ -4,7 +4,6 @@ namespace AgileObjects.AgileMapper.Configuration using System; #endif using Members; - using ReadableExpressions.Extensions; internal class MappedObjectCachingSetting : UserConfiguredItemBase @@ -73,15 +72,12 @@ public string GetConflictMessage(MappedObjectCachingSetting conflicting) return "Identity integrity cannot be configured globally with global object tracking disabled"; } - var targetType = ConfigInfo.TargetType.GetFriendlyName(); - if (ConfigInfo.IsForAllSourceTypes()) { - return GetRedundantSettingConflictMessage(conflicting, " when mapping to " + targetType); + return GetRedundantSettingConflictMessage(conflicting, " when mapping to " + TargetTypeName); } - - var sourceType = ConfigInfo.SourceType.GetFriendlyName(); - var typeSettings = $" when mapping {sourceType} -> {targetType}"; + + var typeSettings = $" when mapping {SourceTypeName} -> {TargetTypeName}"; return GetRedundantSettingConflictMessage(conflicting, typeSettings); } diff --git a/AgileMapper/Configuration/UserConfiguredItemBase.cs b/AgileMapper/Configuration/UserConfiguredItemBase.cs index 413363213..d6ed13d69 100644 --- a/AgileMapper/Configuration/UserConfiguredItemBase.cs +++ b/AgileMapper/Configuration/UserConfiguredItemBase.cs @@ -41,7 +41,13 @@ protected UserConfiguredItemBase(MappingConfigInfo configInfo, QualifiedMember t public MappingConfigInfo ConfigInfo { get; } - public string TargetTypeName => ConfigInfo.TargetType.GetFriendlyName(); + public Type SourceType => ConfigInfo.SourceType; + + public string SourceTypeName => SourceType.GetFriendlyName(); + + public Type TargetType => ConfigInfo.TargetType; + + public string TargetTypeName => TargetType.GetFriendlyName(); public QualifiedMember TargetMember { get; } @@ -229,8 +235,8 @@ protected int DoComparisonTo(UserConfiguredItemBase other) private int OrderAlphabetically(UserConfiguredItemBase other) { return string.Compare( - ConfigInfo.TargetType.Name, - other.ConfigInfo.TargetType.Name, + TargetTypeName, + other.TargetTypeName, StringComparison.Ordinal); } } diff --git a/AgileMapper/Constants.cs b/AgileMapper/Constants.cs index 402217af6..a474497ef 100644 --- a/AgileMapper/Constants.cs +++ b/AgileMapper/Constants.cs @@ -19,7 +19,7 @@ internal static class Constants public const string EnumerableElementName = "[i]"; public static readonly Type[] EmptyTypeArray = Enumerable.EmptyArray; - public static readonly Type AllTypes = typeof(Constants); + public static readonly Type AllTypes = typeof(object); public static readonly Expression EmptyExpression = Expression.Empty(); diff --git a/AgileMapper/DataSources/Factories/ConfiguredDataSourceFactory.cs b/AgileMapper/DataSources/Factories/ConfiguredDataSourceFactory.cs index e2485dd10..d774b054f 100644 --- a/AgileMapper/DataSources/Factories/ConfiguredDataSourceFactory.cs +++ b/AgileMapper/DataSources/Factories/ConfiguredDataSourceFactory.cs @@ -74,7 +74,7 @@ private bool CannotBeReversed(out QualifiedMember targetMember, out string reaso } targetMember = sourceMemberLambda.ToTargetMemberOrNull( - ConfigInfo.SourceType, + SourceType, ConfigInfo.MapperContext, out reason); @@ -121,8 +121,8 @@ public MappingConfigInfo GetReverseConfigInfo() { return _reverseConfigInfo ?? (_reverseConfigInfo = ConfigInfo .Copy() - .ForSourceType(ConfigInfo.TargetType) - .ForTargetType(ConfigInfo.SourceType) + .ForSourceType(TargetType) + .ForTargetType(SourceType) .ForSourceValueType(TargetMember.Type)); } diff --git a/AgileMapper/DerivedTypesCache.cs b/AgileMapper/DerivedTypesCache.cs index 249a9952c..5cae08822 100644 --- a/AgileMapper/DerivedTypesCache.cs +++ b/AgileMapper/DerivedTypesCache.cs @@ -34,7 +34,7 @@ public void AddAssemblies(Assembly[] assemblies) public IList GetTypesDerivedFrom(Type baseType) { - if (baseType.IsSealed() || baseType.IsFromBcl()) + if (baseType.IsInterface() || baseType.IsSealed() || baseType.IsFromBcl()) { return Constants.EmptyTypeArray; } @@ -57,9 +57,11 @@ private IList GetDerivedTypesForType(Type baseType) var assemblyTypes = assemblies .SelectMany(assembly => _typesByAssembly - .GetOrAdd(assembly, GetConcreteTypesFromAssembly)); + .GetOrAdd(assembly, GetRelevantTypesFromAssembly)); - var derivedTypes = assemblyTypes.Filter(baseType, IsDerivedType).ToArray(); + var derivedTypes = assemblyTypes + .Filter(baseType, (bt, dt) => dt.IsDerivedFrom(bt)) + .ToArray(); switch (derivedTypes.Length) { @@ -76,15 +78,8 @@ private IList GetDerivedTypesForType(Type baseType) } } - private static IEnumerable GetConcreteTypesFromAssembly(Assembly assembly) - => assembly.QueryTypes().Filter(t => t.IsClass() && !t.IsAbstract()); - - private static bool IsDerivedType(Type baseType, Type derivedType) - { - return baseType.IsInterface() - ? derivedType.IsAssignableTo(baseType) - : derivedType.IsDerivedFrom(baseType); - } + private static IEnumerable GetRelevantTypesFromAssembly(Assembly assembly) + => assembly.QueryTypes().Filter(t => t.IsClass() && !t.IsAbstract()).ToArray(); internal void Reset() => _derivedTypesByType.Empty(); } diff --git a/AgileMapper/ObjectPopulation/ComplexTypes/ComplexTypeMappingExpressionFactory.cs b/AgileMapper/ObjectPopulation/ComplexTypes/ComplexTypeMappingExpressionFactory.cs index 3d178fe59..926453841 100644 --- a/AgileMapper/ObjectPopulation/ComplexTypes/ComplexTypeMappingExpressionFactory.cs +++ b/AgileMapper/ObjectPopulation/ComplexTypes/ComplexTypeMappingExpressionFactory.cs @@ -64,7 +64,7 @@ private static bool DerivedTypesExistForTarget(IMemberMapperData mapperData) .MapperContext .UserConfigurations .DerivedTypes - .GetImplementationTypePairsFor(mapperData, mapperData.MapperContext); + .GetImplementationTypePairsFor(mapperData); return configuredImplementationTypePairs.Any() || mapperData.GetDerivedTargetTypes().Any(); diff --git a/AgileMapper/Properties/AssemblyInfo.cs b/AgileMapper/Properties/AssemblyInfo.cs index 14839a8c2..f3207dd37 100644 --- a/AgileMapper/Properties/AssemblyInfo.cs +++ b/AgileMapper/Properties/AssemblyInfo.cs @@ -13,6 +13,8 @@ [assembly: InternalsVisibleTo("AgileObjects.AgileMapper.UnitTests.NetCore, PublicKey=0024000004800000940000000602000000240000525341310004000001000100570b21a39fbc3df774a5e60b41cd41078ebae1c9210a3ae4355d518a0abecab27f9346fbfe941618dc835e99ab21b75ff38e5815dceebdd8480dc14c0ee14f5cdcd3ace7f980173238c9d827f95a6f46100ff19a7dcf912c9291bf95dcd64694692a193428f2a35023bbed186f3c8f9769e01e5077a8ea5cabafe5d7948024af")] [assembly: InternalsVisibleTo("AgileObjects.AgileMapper.UnitTests.NetCore2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100570b21a39fbc3df774a5e60b41cd41078ebae1c9210a3ae4355d518a0abecab27f9346fbfe941618dc835e99ab21b75ff38e5815dceebdd8480dc14c0ee14f5cdcd3ace7f980173238c9d827f95a6f46100ff19a7dcf912c9291bf95dcd64694692a193428f2a35023bbed186f3c8f9769e01e5077a8ea5cabafe5d7948024af")] [assembly: InternalsVisibleTo("AgileObjects.AgileMapper.UnitTests.NetCore2_1, PublicKey=0024000004800000940000000602000000240000525341310004000001000100570b21a39fbc3df774a5e60b41cd41078ebae1c9210a3ae4355d518a0abecab27f9346fbfe941618dc835e99ab21b75ff38e5815dceebdd8480dc14c0ee14f5cdcd3ace7f980173238c9d827f95a6f46100ff19a7dcf912c9291bf95dcd64694692a193428f2a35023bbed186f3c8f9769e01e5077a8ea5cabafe5d7948024af")] +[assembly: InternalsVisibleTo("AgileObjects.AgileMapper.UnitTests.NetCore2_2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100570b21a39fbc3df774a5e60b41cd41078ebae1c9210a3ae4355d518a0abecab27f9346fbfe941618dc835e99ab21b75ff38e5815dceebdd8480dc14c0ee14f5cdcd3ace7f980173238c9d827f95a6f46100ff19a7dcf912c9291bf95dcd64694692a193428f2a35023bbed186f3c8f9769e01e5077a8ea5cabafe5d7948024af")] +[assembly: InternalsVisibleTo("AgileObjects.AgileMapper.UnitTests.NetCore3, PublicKey=0024000004800000940000000602000000240000525341310004000001000100570b21a39fbc3df774a5e60b41cd41078ebae1c9210a3ae4355d518a0abecab27f9346fbfe941618dc835e99ab21b75ff38e5815dceebdd8480dc14c0ee14f5cdcd3ace7f980173238c9d827f95a6f46100ff19a7dcf912c9291bf95dcd64694692a193428f2a35023bbed186f3c8f9769e01e5077a8ea5cabafe5d7948024af")] [assembly: InternalsVisibleTo("AgileObjects.AgileMapper.UnitTests.NonParallel, PublicKey=0024000004800000940000000602000000240000525341310004000001000100570b21a39fbc3df774a5e60b41cd41078ebae1c9210a3ae4355d518a0abecab27f9346fbfe941618dc835e99ab21b75ff38e5815dceebdd8480dc14c0ee14f5cdcd3ace7f980173238c9d827f95a6f46100ff19a7dcf912c9291bf95dcd64694692a193428f2a35023bbed186f3c8f9769e01e5077a8ea5cabafe5d7948024af")] [assembly: InternalsVisibleTo("AgileObjects.AgileMapper.UnitTests.Orms, PublicKey=0024000004800000940000000602000000240000525341310004000001000100570b21a39fbc3df774a5e60b41cd41078ebae1c9210a3ae4355d518a0abecab27f9346fbfe941618dc835e99ab21b75ff38e5815dceebdd8480dc14c0ee14f5cdcd3ace7f980173238c9d827f95a6f46100ff19a7dcf912c9291bf95dcd64694692a193428f2a35023bbed186f3c8f9769e01e5077a8ea5cabafe5d7948024af")] [assembly: InternalsVisibleTo("AgileObjects.AgileMapper.UnitTests.Common, PublicKey=0024000004800000940000000602000000240000525341310004000001000100570b21a39fbc3df774a5e60b41cd41078ebae1c9210a3ae4355d518a0abecab27f9346fbfe941618dc835e99ab21b75ff38e5815dceebdd8480dc14c0ee14f5cdcd3ace7f980173238c9d827f95a6f46100ff19a7dcf912c9291bf95dcd64694692a193428f2a35023bbed186f3c8f9769e01e5077a8ea5cabafe5d7948024af")]