Browse Source

Revised AbpAutoMapperExtensibleDtoExtensions and more added tests.

pull/3401/head
Halil İbrahim Kalkan 7 years ago
parent
commit
bb83eccd6f
  1. 24
      framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperExtensibleDtoExtensions.cs
  2. 51
      framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions.cs
  3. 41
      framework/test/Volo.Abp.AutoMapper.Tests/AutoMapper/AbpAutoMapperExtensibleDtoExtensions_Tests.cs
  4. 2
      framework/test/Volo.Abp.AutoMapper.Tests/Volo.Abp.AutoMapper.Tests.csproj
  5. 9
      framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapperTestModule.cs
  6. 4
      framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/SampleClasses/MyMapProfile.cs
  7. 5
      framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/AbpObjectExtendingTestModule.cs
  8. 56
      framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions_Tests.cs

24
framework/src/Volo.Abp.AutoMapper/AutoMapper/AbpAutoMapperExtensibleDtoExtensions.cs

@ -7,7 +7,8 @@ namespace AutoMapper
public static class AbpAutoMapperExtensibleDtoExtensions public static class AbpAutoMapperExtensibleDtoExtensions
{ {
public static IMappingExpression<TSource, TDestination> MapExtraProperties<TSource, TDestination>( public static IMappingExpression<TSource, TDestination> MapExtraProperties<TSource, TDestination>(
this IMappingExpression<TSource, TDestination> mappingExpression) this IMappingExpression<TSource, TDestination> mappingExpression,
MappingPropertyDefinitionCheck definitionCheck = MappingPropertyDefinitionCheck.Both)
where TDestination : IHasExtraProperties where TDestination : IHasExtraProperties
where TSource : IHasExtraProperties where TSource : IHasExtraProperties
{ {
@ -15,28 +16,21 @@ namespace AutoMapper
.ForMember( .ForMember(
x => x.ExtraProperties, x => x.ExtraProperties,
y => y.MapFrom( y => y.MapFrom(
(source, dto, extraProps) => (source, destination, extraProps) =>
{ {
var result = extraProps.IsNullOrEmpty() var result = extraProps.IsNullOrEmpty()
? new Dictionary<string, object>() ? new Dictionary<string, object>()
: new Dictionary<string, object>(extraProps); : new Dictionary<string, object>(extraProps);
var objectExtension = ObjectExtensionManager.Instance.GetOrNull<TDestination>(); HasExtraPropertiesObjectExtendingExtensions
.MapExtraPropertiesTo<TSource, TDestination>(
if (objectExtension != null) source.ExtraProperties,
{ result
foreach (var property in objectExtension.GetProperties()) );
{
if (source.ExtraProperties.ContainsKey(property.Name))
{
result[property.Name] = source.ExtraProperties[property.Name];
}
}
}
return result; return result;
}) })
); );
} }
} }
} }

51
framework/src/Volo.Abp.ObjectExtending/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions.cs

@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using Volo.Abp.Data; using Volo.Abp.Data;
namespace Volo.Abp.ObjectExtending namespace Volo.Abp.ObjectExtending
@ -12,8 +13,8 @@ namespace Volo.Abp.ObjectExtending
/// Checks property definitions (over the <see cref="ObjectExtensionManager"/>) /// Checks property definitions (over the <see cref="ObjectExtensionManager"/>)
/// based on the <paramref name="definitionCheck"/> preference. /// based on the <paramref name="definitionCheck"/> preference.
/// </summary> /// </summary>
/// <typeparam name="TSource"></typeparam> /// <typeparam name="TSource">Source class type</typeparam>
/// <typeparam name="TDestination"></typeparam> /// <typeparam name="TDestination">Destination class type</typeparam>
/// <param name="source">The source object</param> /// <param name="source">The source object</param>
/// <param name="destination">The destination object</param> /// <param name="destination">The destination object</param>
/// <param name="definitionCheck"> /// <param name="definitionCheck">
@ -25,6 +26,34 @@ namespace Volo.Abp.ObjectExtending
MappingPropertyDefinitionCheck definitionCheck = MappingPropertyDefinitionCheck.Both) MappingPropertyDefinitionCheck definitionCheck = MappingPropertyDefinitionCheck.Both)
where TSource : IHasExtraProperties where TSource : IHasExtraProperties
where TDestination : IHasExtraProperties where TDestination : IHasExtraProperties
{
MapExtraPropertiesTo<TSource, TDestination>(
source.ExtraProperties,
destination.ExtraProperties,
definitionCheck
);
}
/// <summary>
/// Copies extra properties from the <paramref name="sourceDictionary"/> object
/// to the <paramref name="destinationDictionary"/> object.
///
/// Checks property definitions (over the <see cref="ObjectExtensionManager"/>)
/// based on the <paramref name="definitionCheck"/> preference.
/// </summary>
/// <typeparam name="TSource">Source class type (for definition check)</typeparam>
/// <typeparam name="TDestination">Destination class type (for definition check)</typeparam>
/// <param name="sourceDictionary">The source dictionary object</param>
/// <param name="destinationDictionary">The destination dictionary object</param>
/// <param name="definitionCheck">
/// Controls which properties to map.
/// </param>
public static void MapExtraPropertiesTo<TSource, TDestination>(
Dictionary<string, object> sourceDictionary,
Dictionary<string, object> destinationDictionary,
MappingPropertyDefinitionCheck definitionCheck = MappingPropertyDefinitionCheck.Both)
where TSource : IHasExtraProperties
where TDestination : IHasExtraProperties
{ {
var sourceObjectExtension = ObjectExtensionManager.Instance.GetOrNull<TSource>(); var sourceObjectExtension = ObjectExtensionManager.Instance.GetOrNull<TSource>();
if (definitionCheck.HasFlag(MappingPropertyDefinitionCheck.Source) && if (definitionCheck.HasFlag(MappingPropertyDefinitionCheck.Source) &&
@ -42,40 +71,40 @@ namespace Volo.Abp.ObjectExtending
if (definitionCheck == MappingPropertyDefinitionCheck.None) if (definitionCheck == MappingPropertyDefinitionCheck.None)
{ {
foreach (var keyValue in source.ExtraProperties) foreach (var keyValue in sourceDictionary)
{ {
destination.ExtraProperties[keyValue.Key] = keyValue.Value; destinationDictionary[keyValue.Key] = keyValue.Value;
} }
} }
else if (definitionCheck == MappingPropertyDefinitionCheck.Source) else if (definitionCheck == MappingPropertyDefinitionCheck.Source)
{ {
foreach (var property in sourceObjectExtension.GetProperties()) foreach (var property in sourceObjectExtension.GetProperties())
{ {
if (!source.ExtraProperties.ContainsKey(property.Name)) if (!sourceDictionary.ContainsKey(property.Name))
{ {
continue; continue;
} }
destination.ExtraProperties[property.Name] = source.ExtraProperties[property.Name]; destinationDictionary[property.Name] = sourceDictionary[property.Name];
} }
} }
else if (definitionCheck == MappingPropertyDefinitionCheck.Destination) else if (definitionCheck == MappingPropertyDefinitionCheck.Destination)
{ {
foreach (var keyValue in source.ExtraProperties) foreach (var keyValue in sourceDictionary)
{ {
if (!destinationObjectExtension.HasProperty(keyValue.Key)) if (!destinationObjectExtension.HasProperty(keyValue.Key))
{ {
continue; continue;
} }
destination.ExtraProperties[keyValue.Key] = keyValue.Value; destinationDictionary[keyValue.Key] = keyValue.Value;
} }
} }
else if(definitionCheck == MappingPropertyDefinitionCheck.Both) else if (definitionCheck == MappingPropertyDefinitionCheck.Both)
{ {
foreach (var property in sourceObjectExtension.GetProperties()) foreach (var property in sourceObjectExtension.GetProperties())
{ {
if (!source.ExtraProperties.ContainsKey(property.Name)) if (!sourceDictionary.ContainsKey(property.Name))
{ {
continue; continue;
} }
@ -85,7 +114,7 @@ namespace Volo.Abp.ObjectExtending
continue; continue;
} }
destination.ExtraProperties[property.Name] = source.ExtraProperties[property.Name]; destinationDictionary[property.Name] = sourceDictionary[property.Name];
} }
} }
else else

41
framework/test/Volo.Abp.AutoMapper.Tests/AutoMapper/AbpAutoMapperExtensibleDtoExtensions_Tests.cs

@ -0,0 +1,41 @@
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.AutoMapper;
using Volo.Abp.Data;
using Volo.Abp.ObjectExtending.TestObjects;
using Volo.Abp.Testing;
using Xunit;
namespace AutoMapper
{
public class AbpAutoMapperExtensibleDtoExtensions_Tests : AbpIntegratedTest<AutoMapperTestModule>
{
private readonly Volo.Abp.ObjectMapping.IObjectMapper _objectMapper;
public AbpAutoMapperExtensibleDtoExtensions_Tests()
{
_objectMapper = ServiceProvider.GetRequiredService<Volo.Abp.ObjectMapping.IObjectMapper>();
}
[Fact]
public void MapExtraPropertiesTo_Should_Only_Map_Defined_Properties_By_Default()
{
var person = new ExtensibleTestPerson()
.SetProperty("Name", "John")
.SetProperty("Age", 42)
.SetProperty("ChildCount", 2)
.SetProperty("Sex", "male");
var personDto = new ExtensibleTestPersonDto()
.SetProperty("ExistingDtoProperty", "existing-value");
_objectMapper.Map(person, personDto);
personDto.GetProperty<string>("Name").ShouldBe("John"); //Defined in both classes
personDto.HasProperty("Age").ShouldBeFalse(); //Not defined on the destination
personDto.HasProperty("ChildCount").ShouldBeFalse(); //Not defined in the source
personDto.HasProperty("Sex").ShouldBeFalse(); //Not defined in both classes
personDto.GetProperty<string>("ExistingDtoProperty").ShouldBe("existing-value"); //Should not clear existing values
}
}
}

2
framework/test/Volo.Abp.AutoMapper.Tests/Volo.Abp.AutoMapper.Tests.csproj

@ -11,7 +11,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Volo.Abp.AutoMapper\Volo.Abp.AutoMapper.csproj" /> <ProjectReference Include="..\..\src\Volo.Abp.AutoMapper\Volo.Abp.AutoMapper.csproj" />
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" /> <ProjectReference Include="..\Volo.Abp.ObjectExtending.Tests\Volo.Abp.ObjectExtending.Tests.csproj" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
</ItemGroup> </ItemGroup>

9
framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapperTestModule.cs

@ -1,9 +1,12 @@
using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Modularity;
using Volo.Abp.Modularity; using Volo.Abp.ObjectExtending;
namespace Volo.Abp.AutoMapper namespace Volo.Abp.AutoMapper
{ {
[DependsOn(typeof(AbpAutoMapperModule))] [DependsOn(
typeof(AbpAutoMapperModule),
typeof(AbpObjectExtendingTestModule)
)]
public class AutoMapperTestModule : AbpModule public class AutoMapperTestModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)

4
framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/SampleClasses/MyMapProfile.cs

@ -1,4 +1,5 @@
using AutoMapper; using AutoMapper;
using Volo.Abp.ObjectExtending.TestObjects;
namespace Volo.Abp.AutoMapper.SampleClasses namespace Volo.Abp.AutoMapper.SampleClasses
{ {
@ -7,6 +8,9 @@ namespace Volo.Abp.AutoMapper.SampleClasses
public MyMapProfile() public MyMapProfile()
{ {
CreateMap<MyEntity, MyEntityDto>().ReverseMap(); CreateMap<MyEntity, MyEntityDto>().ReverseMap();
CreateMap<ExtensibleTestPerson, ExtensibleTestPersonDto>()
.MapExtraProperties();
} }
} }
} }

5
framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/AbpObjectExtendingTestModule.cs

@ -4,7 +4,10 @@ using Volo.Abp.Threading;
namespace Volo.Abp.ObjectExtending namespace Volo.Abp.ObjectExtending
{ {
[DependsOn(typeof(AbpObjectExtendingModule))] [DependsOn(
typeof(AbpObjectExtendingModule),
typeof(AbpTestBaseModule)
)]
public class AbpObjectExtendingTestModule : AbpModule public class AbpObjectExtendingTestModule : AbpModule
{ {
private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner(); private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();

56
framework/test/Volo.Abp.ObjectExtending.Tests/Volo/Abp/ObjectExtending/HasExtraPropertiesObjectExtendingExtensions_Tests.cs

@ -8,6 +8,7 @@ namespace Volo.Abp.ObjectExtending
public class HasExtraPropertiesObjectExtendingExtensions_Tests : AbpObjectExtendingTestBase public class HasExtraPropertiesObjectExtendingExtensions_Tests : AbpObjectExtendingTestBase
{ {
private readonly ExtensibleTestPerson _person; private readonly ExtensibleTestPerson _person;
private readonly ExtensibleTestPersonDto _personDto;
public HasExtraPropertiesObjectExtendingExtensions_Tests() public HasExtraPropertiesObjectExtendingExtensions_Tests()
{ {
@ -16,58 +17,57 @@ namespace Volo.Abp.ObjectExtending
.SetProperty("Age", 42) .SetProperty("Age", 42)
.SetProperty("ChildCount", 2) .SetProperty("ChildCount", 2)
.SetProperty("Sex", "male"); .SetProperty("Sex", "male");
_personDto = new ExtensibleTestPersonDto()
.SetProperty("ExistingDtoProperty", "existing-value");
} }
[Fact] [Fact]
public void MapExtraPropertiesTo_Should_Only_Map_Defined_Properties_By_Default() public void MapExtraPropertiesTo_Should_Only_Map_Defined_Properties_By_Default()
{ {
var personDto = new ExtensibleTestPersonDto(); _person.MapExtraPropertiesTo(_personDto);
_person.MapExtraPropertiesTo(personDto);
personDto.GetProperty<string>("Name").ShouldBe("John"); //Defined in both classes _personDto.GetProperty<string>("Name").ShouldBe("John"); //Defined in both classes
personDto.HasProperty("Age").ShouldBeFalse(); //Not defined on the destination _personDto.HasProperty("Age").ShouldBeFalse(); //Not defined on the destination
personDto.HasProperty("ChildCount").ShouldBeFalse(); //Not defined in the source _personDto.HasProperty("ChildCount").ShouldBeFalse(); //Not defined in the source
personDto.HasProperty("Sex").ShouldBeFalse(); //Not defined in both classes _personDto.HasProperty("Sex").ShouldBeFalse(); //Not defined in both classes
_personDto.GetProperty<string>("ExistingDtoProperty").ShouldBe("existing-value"); //Should not clear existing values
} }
[Fact] [Fact]
public void MapExtraPropertiesTo_Should_Only_Map_Source_Defined_Properties_If_Requested() public void MapExtraPropertiesTo_Should_Only_Map_Source_Defined_Properties_If_Requested()
{ {
var personDto = new ExtensibleTestPersonDto(); _person.MapExtraPropertiesTo(_personDto, MappingPropertyDefinitionCheck.Source);
_person.MapExtraPropertiesTo(personDto, MappingPropertyDefinitionCheck.Source);
personDto.GetProperty<string>("Name").ShouldBe("John"); //Defined in both classes _personDto.GetProperty<string>("Name").ShouldBe("John"); //Defined in both classes
personDto.GetProperty<int>("Age").ShouldBe(42); //Defined in source _personDto.GetProperty<int>("Age").ShouldBe(42); //Defined in source
personDto.HasProperty("ChildCount").ShouldBeFalse(); //Not defined in the source _personDto.HasProperty("ChildCount").ShouldBeFalse(); //Not defined in the source
personDto.HasProperty("Sex").ShouldBeFalse(); //Not defined in both classes _personDto.HasProperty("Sex").ShouldBeFalse(); //Not defined in both classes
_personDto.GetProperty<string>("ExistingDtoProperty").ShouldBe("existing-value"); //Should not clear existing values
} }
[Fact] [Fact]
public void MapExtraPropertiesTo_Should_Only_Map_Destination_Defined_Properties_If_Requested() public void MapExtraPropertiesTo_Should_Only_Map_Destination_Defined_Properties_If_Requested()
{ {
var personDto = new ExtensibleTestPersonDto(); _person.MapExtraPropertiesTo(_personDto, MappingPropertyDefinitionCheck.Destination);
_person.MapExtraPropertiesTo(personDto, MappingPropertyDefinitionCheck.Destination); _personDto.GetProperty<string>("Name").ShouldBe("John"); //Defined in both classes
_personDto.GetProperty<int>("ChildCount").ShouldBe(2); //Defined in destination
personDto.GetProperty<string>("Name").ShouldBe("John"); //Defined in both classes _personDto.HasProperty("Age").ShouldBeFalse(); //Not defined in destination
personDto.GetProperty<int>("ChildCount").ShouldBe(2); //Defined in destination _personDto.HasProperty("Sex").ShouldBeFalse(); //Not defined in both classes
personDto.HasProperty("Age").ShouldBeFalse(); //Not defined in destination _personDto.GetProperty<string>("ExistingDtoProperty").ShouldBe("existing-value"); //Should not clear existing values
personDto.HasProperty("Sex").ShouldBeFalse(); //Not defined in both classes
} }
[Fact] [Fact]
public void MapExtraPropertiesTo_Should_Copy_all_With_No_Property_Definition_Check() public void MapExtraPropertiesTo_Should_Copy_all_With_No_Property_Definition_Check()
{ {
var personDto = new ExtensibleTestPersonDto(); _person.MapExtraPropertiesTo(_personDto, MappingPropertyDefinitionCheck.None);
_person.MapExtraPropertiesTo(personDto, MappingPropertyDefinitionCheck.None);
personDto.GetProperty<string>("Name").ShouldBe("John"); _personDto.GetProperty<string>("Name").ShouldBe("John");
personDto.GetProperty<int>("Age").ShouldBe(42); _personDto.GetProperty<int>("Age").ShouldBe(42);
personDto.GetProperty<int>("ChildCount").ShouldBe(2); _personDto.GetProperty<int>("ChildCount").ShouldBe(2);
personDto.GetProperty<string>("Sex").ShouldBe("male"); _personDto.GetProperty<string>("Sex").ShouldBe("male");
_personDto.GetProperty<string>("ExistingDtoProperty").ShouldBe("existing-value"); //Should not clear existing values
} }
} }
} }

Loading…
Cancel
Save