mirror of https://github.com/abpframework/abp.git
committed by
GitHub
30 changed files with 1101 additions and 4 deletions
@ -0,0 +1,22 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection.Extensions; |
||||
|
using Volo.Abp.Mapperly; |
||||
|
using Volo.Abp.ObjectMapping; |
||||
|
|
||||
|
namespace Microsoft.Extensions.DependencyInjection; |
||||
|
|
||||
|
public static class AbpAutoMapperServiceCollectionExtensions |
||||
|
{ |
||||
|
public static IServiceCollection AddMapperlyObjectMapper(this IServiceCollection services) |
||||
|
{ |
||||
|
return services.Replace( |
||||
|
ServiceDescriptor.Transient<IAutoObjectMappingProvider, MapperlyAutoObjectMappingProvider>() |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
public static IServiceCollection AddMapperlyObjectMapper<TContext>(this IServiceCollection services) |
||||
|
{ |
||||
|
return services.Replace( |
||||
|
ServiceDescriptor.Transient<IAutoObjectMappingProvider<TContext>, MapperlyAutoObjectMappingProvider<TContext>>() |
||||
|
); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\configureawait.props" /> |
||||
|
<Import Project="..\..\..\common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net9.0</TargetFramework> |
||||
|
<Nullable>enable</Nullable> |
||||
|
<WarningsAsErrors>Nullable</WarningsAsErrors> |
||||
|
<AssemblyName>Volo.Abp.Mapperly</AssemblyName> |
||||
|
<PackageId>Volo.Abp.Mapperly</PackageId> |
||||
|
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
||||
|
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
||||
|
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
||||
|
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Volo.Abp.Auditing\Volo.Abp.Auditing.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.ObjectExtending\Volo.Abp.ObjectExtending.csproj" /> |
||||
|
<ProjectReference Include="..\Volo.Abp.ObjectMapping\Volo.Abp.ObjectMapping.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Riok.Mapperly" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
</Project> |
||||
@ -0,0 +1,27 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly; |
||||
|
|
||||
|
public class AbpMapperlyConventionalRegistrar : DefaultConventionalRegistrar |
||||
|
{ |
||||
|
protected override bool IsConventionalRegistrationDisabled(Type type) |
||||
|
{ |
||||
|
return !type.GetInterfaces().Any(x => x.IsGenericType && typeof(IAbpMapperlyMapper<,>) == x.GetGenericTypeDefinition()) || |
||||
|
base.IsConventionalRegistrationDisabled(type); |
||||
|
} |
||||
|
|
||||
|
protected override List<Type> GetExposedServiceTypes(Type type) |
||||
|
{ |
||||
|
var exposedServiceTypes = base.GetExposedServiceTypes(type); |
||||
|
var mapperlyInterfaces = type.GetInterfaces().Where(x => |
||||
|
x.IsGenericType && (typeof(IAbpMapperlyMapper<,>) == x.GetGenericTypeDefinition() || |
||||
|
typeof(IAbpReverseMapperlyMapper<,>) == x.GetGenericTypeDefinition())); |
||||
|
return exposedServiceTypes |
||||
|
.Union(mapperlyInterfaces) |
||||
|
.Distinct() |
||||
|
.ToList(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.Auditing; |
||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.ObjectExtending; |
||||
|
using Volo.Abp.ObjectMapping; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly; |
||||
|
|
||||
|
[DependsOn( |
||||
|
typeof(AbpObjectMappingModule), |
||||
|
typeof(AbpObjectExtendingModule), |
||||
|
typeof(AbpAuditingModule) |
||||
|
)] |
||||
|
public class AbpMapperlyModule : AbpModule |
||||
|
{ |
||||
|
public override void PreConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
context.Services.AddConventionalRegistrar(new AbpMapperlyConventionalRegistrar()); |
||||
|
} |
||||
|
|
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
context.Services.AddMapperlyObjectMapper(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
namespace Volo.Abp.Mapperly; |
||||
|
|
||||
|
public interface IAbpMapperlyMapper<in TSource, TDestination> |
||||
|
{ |
||||
|
TDestination Map(TSource source); |
||||
|
|
||||
|
void Map(TSource source, TDestination destination); |
||||
|
|
||||
|
void BeforeMap(TSource source); |
||||
|
|
||||
|
void AfterMap(TSource source, TDestination destination); |
||||
|
} |
||||
|
|
||||
|
public interface IAbpReverseMapperlyMapper<TSource, TDestination> : IAbpMapperlyMapper<TSource, TDestination> |
||||
|
{ |
||||
|
TSource ReverseMap(TDestination destination); |
||||
|
|
||||
|
void ReverseMap(TDestination destination, TSource source); |
||||
|
|
||||
|
void BeforeReverseMap(TDestination destination); |
||||
|
|
||||
|
void AfterReverseMap(TDestination destination, TSource source); |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp.ObjectExtending; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly; |
||||
|
|
||||
|
[AttributeUsage(AttributeTargets.Class)] |
||||
|
public class MapExtraPropertiesAttribute : Attribute |
||||
|
{ |
||||
|
public MappingPropertyDefinitionChecks DefinitionChecks { get; set; } = MappingPropertyDefinitionChecks.Null; |
||||
|
|
||||
|
public string[]? IgnoredProperties { get; set; } |
||||
|
|
||||
|
public bool MapToRegularProperties { get; set; } |
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly; |
||||
|
|
||||
|
public abstract class MapperBase<TSource, TDestination> : IAbpMapperlyMapper<TSource, TDestination>, ITransientDependency |
||||
|
{ |
||||
|
public abstract TDestination Map(TSource source); |
||||
|
|
||||
|
public abstract void Map(TSource source, TDestination destination); |
||||
|
|
||||
|
public virtual void BeforeMap(TSource source) |
||||
|
{ |
||||
|
} |
||||
|
public virtual void AfterMap(TSource source, TDestination destination) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public abstract class TwoWayMapperBase<TSource, TDestination> : MapperBase<TSource, TDestination>, IAbpReverseMapperlyMapper<TSource, TDestination> |
||||
|
{ |
||||
|
public abstract TSource ReverseMap(TDestination destination); |
||||
|
|
||||
|
public abstract void ReverseMap(TDestination destination, TSource source); |
||||
|
|
||||
|
public virtual void BeforeReverseMap(TDestination destination) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public virtual void AfterReverseMap(TDestination destination, TSource source) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,145 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Reflection; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.Data; |
||||
|
using Volo.Abp.ObjectExtending; |
||||
|
using Volo.Abp.ObjectMapping; |
||||
|
using Volo.Abp.Reflection; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly; |
||||
|
|
||||
|
public class MapperlyAutoObjectMappingProvider<TContext> : MapperlyAutoObjectMappingProvider, IAutoObjectMappingProvider<TContext> |
||||
|
{ |
||||
|
public MapperlyAutoObjectMappingProvider(IServiceProvider serviceProvider) |
||||
|
: base(serviceProvider) |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class MapperlyAutoObjectMappingProvider : IAutoObjectMappingProvider |
||||
|
{ |
||||
|
protected IServiceProvider ServiceProvider { get; } |
||||
|
|
||||
|
public MapperlyAutoObjectMappingProvider(IServiceProvider serviceProvider) |
||||
|
{ |
||||
|
ServiceProvider = serviceProvider; |
||||
|
} |
||||
|
|
||||
|
public virtual TDestination Map<TSource, TDestination>(object source) |
||||
|
{ |
||||
|
var mapper = ServiceProvider.GetService<IAbpMapperlyMapper<TSource, TDestination>>(); |
||||
|
if (mapper != null) |
||||
|
{ |
||||
|
mapper.BeforeMap((TSource)source); |
||||
|
var destination = mapper.Map((TSource)source); |
||||
|
TryMapExtraProperties(mapper.GetType().GetSingleAttributeOrNull<MapExtraPropertiesAttribute>(), (TSource)source, destination, new ExtraPropertyDictionary()); |
||||
|
mapper.AfterMap((TSource)source, destination); |
||||
|
return destination; |
||||
|
} |
||||
|
|
||||
|
var reverseMapper = ServiceProvider.GetService<IAbpReverseMapperlyMapper<TDestination, TSource>>(); |
||||
|
if (reverseMapper != null) |
||||
|
{ |
||||
|
reverseMapper.BeforeReverseMap((TSource)source); |
||||
|
var destination = reverseMapper.ReverseMap((TSource)source); |
||||
|
TryMapExtraProperties(reverseMapper.GetType().GetSingleAttributeOrNull<MapExtraPropertiesAttribute>(), (TSource)source, destination, GetExtraProperties(destination)); |
||||
|
reverseMapper.AfterReverseMap((TSource)source, destination); |
||||
|
return destination; |
||||
|
} |
||||
|
|
||||
|
throw new AbpException($"No {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpMapperlyMapper<TSource, TDestination>))} or" + |
||||
|
$" {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpReverseMapperlyMapper<TSource, TDestination>))} was found"); |
||||
|
} |
||||
|
|
||||
|
public virtual TDestination Map<TSource, TDestination>(TSource source, TDestination destination) |
||||
|
{ |
||||
|
var mapper = ServiceProvider.GetService<IAbpMapperlyMapper<TSource, TDestination>>(); |
||||
|
if (mapper != null) |
||||
|
{ |
||||
|
mapper.BeforeMap(source); |
||||
|
var destinationExtraProperties = GetExtraProperties(destination); |
||||
|
mapper.Map(source, destination); |
||||
|
TryMapExtraProperties(mapper.GetType().GetSingleAttributeOrNull<MapExtraPropertiesAttribute>(), source, destination, destinationExtraProperties); |
||||
|
mapper.AfterMap(source, destination); |
||||
|
return destination; |
||||
|
} |
||||
|
|
||||
|
var reverseMapper = ServiceProvider.GetService<IAbpReverseMapperlyMapper<TDestination, TSource>>(); |
||||
|
if (reverseMapper != null) |
||||
|
{ |
||||
|
reverseMapper.BeforeReverseMap(source); |
||||
|
var destinationExtraProperties = GetExtraProperties(destination); |
||||
|
reverseMapper.ReverseMap(source, destination); |
||||
|
TryMapExtraProperties(reverseMapper.GetType().GetSingleAttributeOrNull<MapExtraPropertiesAttribute>(), source, destination, destinationExtraProperties); |
||||
|
reverseMapper.AfterReverseMap(source, destination); |
||||
|
return destination; |
||||
|
} |
||||
|
|
||||
|
throw new AbpException($"No {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpMapperlyMapper<TSource, TDestination>))} or" + |
||||
|
$" {TypeHelper.GetFullNameHandlingNullableAndGenerics(typeof(IAbpReverseMapperlyMapper<TSource, TDestination>))} was found"); |
||||
|
} |
||||
|
|
||||
|
protected virtual ExtraPropertyDictionary GetExtraProperties<TDestination>(TDestination destination) |
||||
|
{ |
||||
|
var extraProperties = new ExtraPropertyDictionary(); |
||||
|
if (destination is not IHasExtraProperties hasExtraProperties) |
||||
|
{ |
||||
|
return extraProperties; |
||||
|
} |
||||
|
|
||||
|
foreach (var property in hasExtraProperties.ExtraProperties) |
||||
|
{ |
||||
|
extraProperties.Add(property.Key, property.Value); |
||||
|
} |
||||
|
return extraProperties; |
||||
|
} |
||||
|
|
||||
|
protected virtual void TryMapExtraProperties<TSource, TDestination>(MapExtraPropertiesAttribute? mapExtraPropertiesAttribute, TSource source, TDestination destination, ExtraPropertyDictionary destinationExtraProperty) |
||||
|
{ |
||||
|
if (mapExtraPropertiesAttribute != null && |
||||
|
typeof(IHasExtraProperties).IsAssignableFrom(typeof(TDestination)) && |
||||
|
typeof(IHasExtraProperties).IsAssignableFrom(typeof(TSource))) |
||||
|
{ |
||||
|
MapExtraProperties<TSource, TDestination>( |
||||
|
source!.As<IHasExtraProperties>(), |
||||
|
destination!.As<IHasExtraProperties>(), |
||||
|
destinationExtraProperty, |
||||
|
mapExtraPropertiesAttribute.DefinitionChecks, |
||||
|
mapExtraPropertiesAttribute.IgnoredProperties, |
||||
|
mapExtraPropertiesAttribute.MapToRegularProperties |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
protected virtual void MapExtraProperties<TSource, TDestination>( |
||||
|
IHasExtraProperties source, |
||||
|
IHasExtraProperties destination, |
||||
|
ExtraPropertyDictionary destinationExtraProperty, |
||||
|
MappingPropertyDefinitionChecks? definitionChecks = null, |
||||
|
string[]? ignoredProperties = null, |
||||
|
bool mapToRegularProperties = false) |
||||
|
{ |
||||
|
var result = destinationExtraProperty.IsNullOrEmpty() |
||||
|
? new Dictionary<string, object?>() |
||||
|
: new Dictionary<string, object?>(destinationExtraProperty); |
||||
|
|
||||
|
if (source.ExtraProperties != null && destination.ExtraProperties != null) |
||||
|
{ |
||||
|
ExtensibleObjectMapper |
||||
|
.MapExtraPropertiesTo( |
||||
|
typeof(TSource), |
||||
|
typeof(TDestination), |
||||
|
source.ExtraProperties, |
||||
|
result, |
||||
|
definitionChecks, |
||||
|
ignoredProperties |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
ObjectHelper.TrySetProperty(destination, x => x.ExtraProperties, () => new ExtraPropertyDictionary(result)); |
||||
|
if (mapToRegularProperties) |
||||
|
{ |
||||
|
destination.SetExtraPropertiesToRegularProperties(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,82 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.Data; |
||||
|
using Volo.Abp.Mapperly; |
||||
|
using Volo.Abp.ObjectExtending.TestObjects; |
||||
|
using Volo.Abp.Testing; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Mapperly; |
||||
|
|
||||
|
public class AbpAutoMapperExtensibleDtoExtensions_Tests : AbpIntegratedTest<MapperlyTestModule> |
||||
|
{ |
||||
|
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") |
||||
|
.SetProperty("CityName", "Adana"); |
||||
|
|
||||
|
var personDto = new ExtensibleTestPersonDto() |
||||
|
.SetProperty("ExistingDtoProperty", "existing-value"); |
||||
|
|
||||
|
_objectMapper.Map(person, personDto); |
||||
|
|
||||
|
personDto.GetProperty<string>("Name").ShouldBe("John"); //Defined in both classes
|
||||
|
personDto.GetProperty<string>("ExistingDtoProperty").ShouldBe("existing-value"); //Should not clear existing values
|
||||
|
personDto.GetProperty<int>("ChildCount").ShouldBe(0); //Not defined in the source, but was set to the default value by ExtensibleTestPersonDto constructor
|
||||
|
personDto.GetProperty("CityName").ShouldBeNull(); //Ignored, but was set to the default value by ExtensibleTestPersonDto constructor
|
||||
|
personDto.HasProperty("Age").ShouldBeFalse(); //Not defined on the destination
|
||||
|
personDto.HasProperty("Sex").ShouldBeFalse(); //Not defined in both classes
|
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void MapExtraProperties_Also_Should_Map_To_RegularProperties() |
||||
|
{ |
||||
|
var person = new ExtensibleTestPerson() |
||||
|
.SetProperty("Name", "John") |
||||
|
.SetProperty("Age", 42); |
||||
|
|
||||
|
var personDto = new ExtensibleTestPersonWithRegularPropertiesDto() |
||||
|
.SetProperty("IsActive", true); |
||||
|
|
||||
|
_objectMapper.Map(person, personDto); |
||||
|
|
||||
|
//Defined in both classes
|
||||
|
personDto.HasProperty("Name").ShouldBe(false); |
||||
|
personDto.Name.ShouldBe("John"); |
||||
|
|
||||
|
//Defined in both classes
|
||||
|
personDto.HasProperty("Age").ShouldBe(false); |
||||
|
personDto.Age.ShouldBe(42); |
||||
|
|
||||
|
//Should not clear existing values
|
||||
|
personDto.HasProperty("IsActive").ShouldBe(false); |
||||
|
personDto.IsActive.ShouldBe(true); |
||||
|
} |
||||
|
|
||||
|
[Fact(Skip = "Mapperly requires IHasExtraProperties.ExtraPropertyDictionary to be marked as nullable")] |
||||
|
public void MapExtraPropertiesTo_Should_Ignored_If_ExtraProperties_Is_Null() |
||||
|
{ |
||||
|
var person = new ExtensibleTestPerson(); |
||||
|
person.SetExtraPropertiesAsNull(); |
||||
|
|
||||
|
var personDto = new ExtensibleTestPersonDto(); |
||||
|
personDto.SetExtraPropertiesAsNull(); |
||||
|
|
||||
|
Should.NotThrow(() => _objectMapper.Map(person, personDto)); |
||||
|
|
||||
|
person.ExtraProperties.ShouldBe(null); |
||||
|
personDto.ExtraProperties.ShouldBeEmpty(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
|
||||
|
<Import Project="..\..\..\common.test.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>net9.0</TargetFramework> |
||||
|
<AssemblyName>Volo.Abp.Mapperly.Tests</AssemblyName> |
||||
|
<PackageId>Volo.Abp.Mapperly.Tests</PackageId> |
||||
|
<RootNamespace /> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\src\Volo.Abp.Mapperly\Volo.Abp.Mapperly.csproj" /> |
||||
|
<ProjectReference Include="..\..\test\Volo.Abp.ObjectExtending.Tests\Volo.Abp.ObjectExtending.Tests.csproj" /> |
||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" /> |
||||
|
</ItemGroup> |
||||
|
</Project> |
||||
@ -0,0 +1,59 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Riok.Mapperly.Abstractions; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.ObjectMapping; |
||||
|
using Volo.Abp.Testing; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly; |
||||
|
|
||||
|
public class MyClass |
||||
|
{ |
||||
|
public string Id { get; set; } |
||||
|
|
||||
|
public string Name { get; set; } |
||||
|
} |
||||
|
|
||||
|
public class MyClassDto |
||||
|
{ |
||||
|
public string Id { get; set; } |
||||
|
|
||||
|
public string Name { get; set; } |
||||
|
} |
||||
|
|
||||
|
[Mapper] |
||||
|
public partial class MyClassMapper : MapperBase<MyClass, MyClassDto> |
||||
|
{ |
||||
|
public override partial MyClassDto Map(MyClass source); |
||||
|
|
||||
|
public override partial void Map(MyClass source, MyClassDto destination); |
||||
|
|
||||
|
public override void BeforeMap(MyClass source) |
||||
|
{ |
||||
|
source.Name = "BeforeMap " + source.Name; |
||||
|
} |
||||
|
|
||||
|
public override void AfterMap(MyClass source, MyClassDto destination) |
||||
|
{ |
||||
|
destination.Name = source.Name + " AfterMap"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class AbpMapperlyBeforeAndAfterMethod_Tests : AbpIntegratedTest<MapperlyTestModule> |
||||
|
{ |
||||
|
private readonly IObjectMapper _objectMapper; |
||||
|
|
||||
|
public AbpMapperlyBeforeAndAfterMethod_Tests() |
||||
|
{ |
||||
|
_objectMapper = ServiceProvider.GetRequiredService<IObjectMapper>(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void BeforeAndAfterMethods_Should_Be_Called_When_Mapping() |
||||
|
{ |
||||
|
var myClass = new MyClass { Id = "1", Name = "Test" }; |
||||
|
|
||||
|
var myClassDto = _objectMapper.Map<MyClass, MyClassDto>(myClass); |
||||
|
myClassDto.Name.ShouldBe("BeforeMap Test AfterMap"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,60 @@ |
|||||
|
using System; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.Mapperly.SampleClasses; |
||||
|
using Volo.Abp.ObjectMapping; |
||||
|
using Volo.Abp.Testing; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly; |
||||
|
|
||||
|
public class AbpMapperlyModule_Basic_Tests : AbpIntegratedTest<MapperlyTestModule> |
||||
|
{ |
||||
|
private readonly IObjectMapper _objectMapper; |
||||
|
|
||||
|
public AbpMapperlyModule_Basic_Tests() |
||||
|
{ |
||||
|
_objectMapper = ServiceProvider.GetRequiredService<IObjectMapper>(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Replace_IAutoObjectMappingProvider() |
||||
|
{ |
||||
|
Assert.True(ServiceProvider.GetRequiredService<IAutoObjectMappingProvider>() is MapperlyAutoObjectMappingProvider); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Map_Objects_With_AutoMap_Attributes() |
||||
|
{ |
||||
|
var dto = _objectMapper.Map<MyEntity, MyEntityDto>(new MyEntity { Number = 42 }); |
||||
|
dto.Number.ShouldBe(42); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Map_Objects_With_Existing_Target_Object() |
||||
|
{ |
||||
|
var dto = new MyEntityDto {Id = Guid.Empty, Number = 42}; |
||||
|
|
||||
|
_objectMapper.Map<MyEntity, MyEntityDto>(new MyEntity { Id = Guid.NewGuid(), Number = 43 }, dto); |
||||
|
|
||||
|
dto.Number.ShouldBe(43); |
||||
|
dto.Id.ShouldNotBe(Guid.Empty); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Map_Enum() |
||||
|
{ |
||||
|
var dto = _objectMapper.Map<MyEnum, MyEnumDto>(MyEnum.Value3); |
||||
|
dto.ShouldBe(MyEnumDto.Value2); //Value2 is same as Value3
|
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Throw_Exception_If_Mapper_Is_Not_Found() |
||||
|
{ |
||||
|
var exception = Assert.Throws<AbpException>(() =>_objectMapper.Map<MyEntity, MyClassDto>(new MyEntity())); |
||||
|
exception.Message.ShouldBe("No " + |
||||
|
"Volo.Abp.Mapperly.IAbpMapperlyMapper<Volo.Abp.Mapperly.SampleClasses.MyEntity,Volo.Abp.Mapperly.MyClassDto> or " + |
||||
|
"Volo.Abp.Mapperly.IAbpReverseMapperlyMapper<Volo.Abp.Mapperly.SampleClasses.MyEntity,Volo.Abp.Mapperly.MyClassDto>" + |
||||
|
" was found"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,191 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Collections.ObjectModel; |
||||
|
using System.Linq; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.Mapperly.SampleClasses; |
||||
|
using Volo.Abp.ObjectMapping; |
||||
|
using Volo.Abp.Testing; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly; |
||||
|
|
||||
|
public class AbpMapperlyModule_Specific_ObjectMapper_Tests : AbpIntegratedTest<MapperlyTestModule> |
||||
|
{ |
||||
|
private readonly IObjectMapper _objectMapper; |
||||
|
|
||||
|
public AbpMapperlyModule_Specific_ObjectMapper_Tests() |
||||
|
{ |
||||
|
_objectMapper = ServiceProvider.GetRequiredService<IObjectMapper>(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Use_Specific_Object_Mapper_If_Registered() |
||||
|
{ |
||||
|
var dto = _objectMapper.Map<MyEntity, MyEntityDto2>(new MyEntity { Number = 42 }); |
||||
|
dto.Number.ShouldBe(43); //MyEntityToMyEntityDto2Mapper adds 1 to number of the source.
|
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Specific_Object_Mapper_Should_Be_Used_For_Collections_If_Registered() |
||||
|
{ |
||||
|
// IEnumerable
|
||||
|
_objectMapper.Map<IEnumerable<MyEntity>, IEnumerable<MyEntityDto2>>(new List<MyEntity>() |
||||
|
{ |
||||
|
new MyEntity { Number = 42 } |
||||
|
}).First().Number.ShouldBe(43); //MyEntityToMyEntityDto2Mapper adds 1 to number of the source.
|
||||
|
|
||||
|
var destination = new List<MyEntityDto2>() |
||||
|
{ |
||||
|
new MyEntityDto2 { Number = 44 } |
||||
|
}; |
||||
|
var returnIEnumerable = _objectMapper.Map<IEnumerable<MyEntity>, IEnumerable<MyEntityDto2>>( |
||||
|
new List<MyEntity>() |
||||
|
{ |
||||
|
new MyEntity { Number = 42 } |
||||
|
}, destination); |
||||
|
returnIEnumerable.First().Number.ShouldBe(43); |
||||
|
ReferenceEquals(destination, returnIEnumerable).ShouldBeTrue(); |
||||
|
|
||||
|
// ICollection
|
||||
|
_objectMapper.Map<ICollection<MyEntity>, ICollection<MyEntityDto2>>(new List<MyEntity>() |
||||
|
{ |
||||
|
new MyEntity { Number = 42 } |
||||
|
}).First().Number.ShouldBe(43); //MyEntityToMyEntityDto2Mapper adds 1 to number of the source.
|
||||
|
|
||||
|
var returnICollection = _objectMapper.Map<ICollection<MyEntity>, ICollection<MyEntityDto2>>( |
||||
|
new List<MyEntity>() |
||||
|
{ |
||||
|
new MyEntity { Number = 42 } |
||||
|
}, destination); |
||||
|
returnICollection.First().Number.ShouldBe(43); |
||||
|
ReferenceEquals(destination, returnICollection).ShouldBeTrue(); |
||||
|
|
||||
|
// Collection
|
||||
|
_objectMapper.Map<Collection<MyEntity>, Collection<MyEntityDto2>>(new Collection<MyEntity>() |
||||
|
{ |
||||
|
new MyEntity { Number = 42 } |
||||
|
}).First().Number.ShouldBe(43); //MyEntityToMyEntityDto2Mapper adds 1 to number of the source.
|
||||
|
|
||||
|
var destination2 = new Collection<MyEntityDto2>() |
||||
|
{ |
||||
|
new MyEntityDto2 { Number = 44 } |
||||
|
}; |
||||
|
var returnCollection = _objectMapper.Map<Collection<MyEntity>, Collection<MyEntityDto2>>( |
||||
|
new Collection<MyEntity>() |
||||
|
{ |
||||
|
new MyEntity { Number = 42 } |
||||
|
}, destination2); |
||||
|
returnCollection.First().Number.ShouldBe(43); |
||||
|
ReferenceEquals(destination2, returnCollection).ShouldBeTrue(); |
||||
|
|
||||
|
// IList
|
||||
|
_objectMapper.Map<IList<MyEntity>, IList<MyEntityDto2>>(new List<MyEntity>() |
||||
|
{ |
||||
|
new MyEntity { Number = 42 } |
||||
|
}).First().Number.ShouldBe(43); //MyEntityToMyEntityDto2Mapper adds 1 to number of the source.
|
||||
|
|
||||
|
var returnIList = _objectMapper.Map<IList<MyEntity>, IList<MyEntityDto2>>( |
||||
|
new List<MyEntity>() |
||||
|
{ |
||||
|
new MyEntity { Number = 42 } |
||||
|
}, destination); |
||||
|
returnIList.First().Number.ShouldBe(43); |
||||
|
ReferenceEquals(destination, returnIList).ShouldBeTrue(); |
||||
|
|
||||
|
// List
|
||||
|
_objectMapper.Map<List<MyEntity>, List<MyEntityDto2>>(new List<MyEntity>() |
||||
|
{ |
||||
|
new MyEntity { Number = 42 } |
||||
|
}).First().Number.ShouldBe(43); //MyEntityToMyEntityDto2Mapper adds 1 to number of the source.
|
||||
|
|
||||
|
var returnList = _objectMapper.Map<List<MyEntity>, List<MyEntityDto2>>( |
||||
|
new List<MyEntity>() |
||||
|
{ |
||||
|
new MyEntity { Number = 42 } |
||||
|
}, destination); |
||||
|
returnList.First().Number.ShouldBe(43); |
||||
|
ReferenceEquals(destination, returnList).ShouldBeTrue(); |
||||
|
|
||||
|
// Array
|
||||
|
_objectMapper.Map<MyEntity[], MyEntityDto2[]>(new MyEntity[] |
||||
|
{ |
||||
|
new MyEntity { Number = 42 } |
||||
|
}).First().Number.ShouldBe(43); //MyEntityToMyEntityDto2Mapper adds 1 to number of the source.
|
||||
|
|
||||
|
var destinationArray = new MyEntityDto2[] |
||||
|
{ |
||||
|
new MyEntityDto2 { Number = 40 } |
||||
|
}; |
||||
|
var returnArray = _objectMapper.Map<MyEntity[], MyEntityDto2[]>(new MyEntity[] |
||||
|
{ |
||||
|
new MyEntity { Number = 42 } |
||||
|
}, destinationArray); |
||||
|
|
||||
|
returnArray.First().Number.ShouldBe(43); |
||||
|
|
||||
|
// array should not be changed. Same as Mapperly.
|
||||
|
destinationArray.First().Number.ShouldBe(40); |
||||
|
ReferenceEquals(returnArray, destinationArray).ShouldBeFalse(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Specific_Object_Mapper_Should_Support_Multiple_IObjectMapper_Interfaces() |
||||
|
{ |
||||
|
var myEntityDto2 = _objectMapper.Map<MyEntity, MyEntityDto2>(new MyEntity { Number = 42 }); |
||||
|
myEntityDto2.Number.ShouldBe(43); //MyEntityToMyEntityDto2Mapper adds 1 to number of the source.
|
||||
|
|
||||
|
var myEntity = _objectMapper.Map<MyEntityDto2, MyEntity>(new MyEntityDto2 { Number = 42 }); |
||||
|
myEntity.Number.ShouldBe(43); //MyEntityToMyEntityDto2Mapper adds 1 to number of the source.
|
||||
|
|
||||
|
// IEnumerable
|
||||
|
_objectMapper.Map<IEnumerable<MyEntity>, IEnumerable<MyEntityDto2>>(new List<MyEntity>() |
||||
|
{ |
||||
|
new MyEntity { Number = 42 } |
||||
|
}).First().Number.ShouldBe(43); //MyEntityToMyEntityDto2Mapper adds 1 to number of the source.
|
||||
|
|
||||
|
_objectMapper.Map<IEnumerable<MyEntityDto2>, IEnumerable<MyEntity>>(new List<MyEntityDto2>() |
||||
|
{ |
||||
|
new MyEntityDto2 { Number = 42 } |
||||
|
}).First().Number.ShouldBe(43); //MyEntityToMyEntityDto2Mapper adds 1 to number of the source.
|
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Use_Destination_Object_Constructor_If_Available() |
||||
|
{ |
||||
|
var id = Guid.NewGuid(); |
||||
|
var dto = _objectMapper.Map<MyEntity, MyEntityDtoWithMappingMethods>(new MyEntity { Number = 42, Id = id }); |
||||
|
dto.Key.ShouldBe(id); |
||||
|
dto.No.ShouldBe(42); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Use_Destination_Object_MapFrom_Method_If_Available() |
||||
|
{ |
||||
|
var id = Guid.NewGuid(); |
||||
|
var dto = new MyEntityDtoWithMappingMethods(); |
||||
|
_objectMapper.Map(new MyEntity { Number = 42, Id = id }, dto); |
||||
|
dto.Key.ShouldBe(id); |
||||
|
dto.No.ShouldBe(42); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Use_Source_Object_Method_If_Available_To_Create_New_Object() |
||||
|
{ |
||||
|
var id = Guid.NewGuid(); |
||||
|
var entity = _objectMapper.Map<MyEntityDtoWithMappingMethods, MyEntity>(new MyEntityDtoWithMappingMethods { Key = id, No = 42 }); |
||||
|
entity.Id.ShouldBe(id); |
||||
|
entity.Number.ShouldBe(42); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_Use_Source_Object_Method_If_Available_To_Map_Existing_Object() |
||||
|
{ |
||||
|
var id = Guid.NewGuid(); |
||||
|
var entity = new MyEntity(); |
||||
|
_objectMapper.Map(new MyEntityDtoWithMappingMethods { Key = id, No = 42 }, entity); |
||||
|
entity.Id.ShouldBe(id); |
||||
|
entity.Number.ShouldBe(42); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,68 @@ |
|||||
|
using System; |
||||
|
using Riok.Mapperly.Abstractions; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.ObjectMapping; |
||||
|
using Volo.Abp.Testing; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly; |
||||
|
|
||||
|
public class MyDIClass |
||||
|
{ |
||||
|
public string Id { get; set; } |
||||
|
|
||||
|
public DateTime Birthday { get; set; } |
||||
|
} |
||||
|
|
||||
|
public class MyDIClassDto |
||||
|
{ |
||||
|
public string Id { get; set; } |
||||
|
|
||||
|
public DateTime Birthday { get; set; } |
||||
|
} |
||||
|
|
||||
|
public class BirthdayCalculatorService : ITransientDependency |
||||
|
{ |
||||
|
public DateTime Birthday => DateTime.Parse("2025-01-01"); |
||||
|
} |
||||
|
|
||||
|
[Mapper] |
||||
|
public partial class MyDIClassMapper : MapperBase<MyDIClass, MyDIClassDto> |
||||
|
{ |
||||
|
private readonly BirthdayCalculatorService _birthdayCalculatorService; |
||||
|
|
||||
|
public MyDIClassMapper(BirthdayCalculatorService birthdayCalculatorService) |
||||
|
{ |
||||
|
_birthdayCalculatorService = birthdayCalculatorService; |
||||
|
} |
||||
|
|
||||
|
public override partial MyDIClassDto Map(MyDIClass source); |
||||
|
|
||||
|
public override partial void Map(MyDIClass source, MyDIClassDto destination); |
||||
|
|
||||
|
public override void AfterMap(MyDIClass source, MyDIClassDto destination) |
||||
|
{ |
||||
|
destination.Birthday = _birthdayCalculatorService.Birthday; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class AbpMapperly_Dependency_Injection_Tests : AbpIntegratedTest<MapperlyTestModule> |
||||
|
{ |
||||
|
private readonly IObjectMapper _objectMapper; |
||||
|
private readonly BirthdayCalculatorService _birthdayCalculatorService; |
||||
|
|
||||
|
public AbpMapperly_Dependency_Injection_Tests() |
||||
|
{ |
||||
|
_objectMapper = GetRequiredService<IObjectMapper>(); |
||||
|
_birthdayCalculatorService = GetRequiredService<BirthdayCalculatorService>(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void DI_Test() |
||||
|
{ |
||||
|
var myClass = new MyDIClass { Id = "1", Birthday = DateTime.Now }; |
||||
|
var myClassDto = _objectMapper.Map<MyDIClass, MyDIClassDto>(myClass); |
||||
|
myClassDto.Birthday.ShouldBe(_birthdayCalculatorService.Birthday); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,86 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Riok.Mapperly.Abstractions; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.ObjectMapping; |
||||
|
using Volo.Abp.Testing; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly; |
||||
|
|
||||
|
public class MyReverseClass |
||||
|
{ |
||||
|
public string Id { get; set; } |
||||
|
|
||||
|
public string Name { get; set; } |
||||
|
} |
||||
|
|
||||
|
public class MyReverseClassDto |
||||
|
{ |
||||
|
public string Id { get; set; } |
||||
|
|
||||
|
public string Name { get; set; } |
||||
|
} |
||||
|
|
||||
|
[Mapper] |
||||
|
public partial class MyReverseClassMapper : TwoWayMapperBase<MyReverseClass, MyReverseClassDto> |
||||
|
{ |
||||
|
public override partial MyReverseClassDto Map(MyReverseClass source); |
||||
|
|
||||
|
public override partial void Map(MyReverseClass source, MyReverseClassDto destination); |
||||
|
|
||||
|
public override partial MyReverseClass ReverseMap(MyReverseClassDto destination); |
||||
|
|
||||
|
public override partial void ReverseMap(MyReverseClassDto destination, MyReverseClass source); |
||||
|
|
||||
|
public override void BeforeReverseMap(MyReverseClassDto destination) |
||||
|
{ |
||||
|
destination.Name = "BeforeReverseMap " + destination.Name; |
||||
|
} |
||||
|
|
||||
|
public override void AfterReverseMap(MyReverseClassDto destination, MyReverseClass source) |
||||
|
{ |
||||
|
source.Name = destination.Name + " AfterReverseMap"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class AbpReverseMapperly_Tests : AbpIntegratedTest<MapperlyTestModule> |
||||
|
{ |
||||
|
private readonly IObjectMapper _objectMapper; |
||||
|
|
||||
|
public AbpReverseMapperly_Tests() |
||||
|
{ |
||||
|
_objectMapper = ServiceProvider.GetRequiredService<IObjectMapper>(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Map_Test() |
||||
|
{ |
||||
|
var myClass = new MyReverseClass { Id = "1", Name = "Test" }; |
||||
|
var myClassDto = _objectMapper.Map<MyReverseClass, MyReverseClassDto>(myClass); |
||||
|
myClassDto.Name.ShouldBe("Test"); |
||||
|
|
||||
|
myClass.Id = "2"; |
||||
|
myClass.Name = "Test2"; |
||||
|
|
||||
|
_objectMapper.Map<MyReverseClass, MyReverseClassDto>(myClass, myClassDto); |
||||
|
|
||||
|
myClassDto.Id.ShouldBe("2"); |
||||
|
myClassDto.Name.ShouldBe("Test2"); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void ReverseMap_Test() |
||||
|
{ |
||||
|
var myClassDto = new MyReverseClassDto { Id = "1", Name = "Test" }; |
||||
|
var myClass = _objectMapper.Map<MyReverseClassDto, MyReverseClass>(myClassDto); |
||||
|
myClass.Name.ShouldBe("BeforeReverseMap Test AfterReverseMap"); |
||||
|
|
||||
|
myClassDto.Id = "2"; |
||||
|
myClassDto.Name = "Test2"; |
||||
|
|
||||
|
_objectMapper.Map<MyReverseClassDto, MyReverseClass>(myClassDto, myClass); |
||||
|
|
||||
|
myClass.Id.ShouldBe("2"); |
||||
|
myClass.Name.ShouldBe("BeforeReverseMap Test2 AfterReverseMap"); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,13 @@ |
|||||
|
using Volo.Abp.Modularity; |
||||
|
using Volo.Abp.ObjectExtending; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly; |
||||
|
|
||||
|
[DependsOn( |
||||
|
typeof(AbpMapperlyModule), |
||||
|
typeof(AbpObjectExtendingTestModule) |
||||
|
)] |
||||
|
public class MapperlyTestModule : AbpModule |
||||
|
{ |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,44 @@ |
|||||
|
using Riok.Mapperly.Abstractions; |
||||
|
using Volo.Abp.Mapperly; |
||||
|
using Volo.Abp.Mapperly.SampleClasses; |
||||
|
using Volo.Abp.ObjectExtending.TestObjects; |
||||
|
|
||||
|
[Mapper] |
||||
|
public partial class MyEntityMapper : MapperBase<MyEntity, MyEntityDto> |
||||
|
{ |
||||
|
public override partial MyEntityDto Map(MyEntity source); |
||||
|
|
||||
|
public override partial void Map(MyEntity source, MyEntityDto destination); |
||||
|
} |
||||
|
|
||||
|
[Mapper] |
||||
|
public partial class MyEnumMapper : MapperBase<MyEnum, MyEnumDto> |
||||
|
{ |
||||
|
public override partial MyEnumDto Map(MyEnum source); |
||||
|
|
||||
|
public override void Map(MyEnum source, MyEnumDto destination) |
||||
|
{ |
||||
|
destination = Map(source); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Mapper] |
||||
|
[MapExtraProperties(IgnoredProperties = ["CityName"])] |
||||
|
public partial class ExtensibleTestPersonMapper : MapperBase<ExtensibleTestPerson, ExtensibleTestPersonDto> |
||||
|
{ |
||||
|
public override partial ExtensibleTestPersonDto Map(ExtensibleTestPerson source); |
||||
|
|
||||
|
public override partial void Map(ExtensibleTestPerson source, ExtensibleTestPersonDto destination); |
||||
|
} |
||||
|
|
||||
|
[Mapper] |
||||
|
[MapExtraProperties(MapToRegularProperties = true)] |
||||
|
public partial class ExtensibleTestPersonWithRegularPropertiesDtoMapper : MapperBase<ExtensibleTestPerson, ExtensibleTestPersonWithRegularPropertiesDto> |
||||
|
{ |
||||
|
[MapperIgnoreTarget(nameof(ExtensibleTestPersonWithRegularPropertiesDto.Name))] |
||||
|
[MapperIgnoreTarget(nameof(ExtensibleTestPersonWithRegularPropertiesDto.Age))] |
||||
|
[MapperIgnoreTarget(nameof(ExtensibleTestPersonWithRegularPropertiesDto.IsActive))] |
||||
|
public override partial ExtensibleTestPersonWithRegularPropertiesDto Map(ExtensibleTestPerson source); |
||||
|
|
||||
|
public override partial void Map(ExtensibleTestPerson source, ExtensibleTestPersonWithRegularPropertiesDto destination); |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly.SampleClasses; |
||||
|
|
||||
|
public class MyEntity |
||||
|
{ |
||||
|
public Guid Id { get; set; } |
||||
|
|
||||
|
public int Number { get; set; } |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly.SampleClasses; |
||||
|
|
||||
|
public class MyEntityDto |
||||
|
{ |
||||
|
public Guid Id { get; set; } |
||||
|
|
||||
|
public int Number { get; set; } |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly.SampleClasses; |
||||
|
|
||||
|
public class MyEntityDto2 |
||||
|
{ |
||||
|
public Guid Id { get; set; } |
||||
|
|
||||
|
public int Number { get; set; } |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp.ObjectMapping; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly.SampleClasses; |
||||
|
|
||||
|
//TODO: Move tests to Volo.Abp.ObjectMapping test project
|
||||
|
public class MyEntityDtoWithMappingMethods : IMapFrom<MyEntity>, IMapTo<MyEntity> |
||||
|
{ |
||||
|
public Guid Key { get; set; } |
||||
|
|
||||
|
public int No { get; set; } |
||||
|
|
||||
|
public MyEntityDtoWithMappingMethods() |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public MyEntityDtoWithMappingMethods(MyEntity entity) |
||||
|
{ |
||||
|
MapFrom(entity); |
||||
|
} |
||||
|
|
||||
|
public void MapFrom(MyEntity source) |
||||
|
{ |
||||
|
Key = source.Id; |
||||
|
No = source.Number; |
||||
|
} |
||||
|
|
||||
|
MyEntity IMapTo<MyEntity>.MapTo() |
||||
|
{ |
||||
|
return new MyEntity |
||||
|
{ |
||||
|
Id = Key, |
||||
|
Number = No |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
void IMapTo<MyEntity>.MapTo(MyEntity destination) |
||||
|
{ |
||||
|
destination.Id = Key; |
||||
|
destination.Number = No; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.ObjectMapping; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly.SampleClasses; |
||||
|
|
||||
|
public class MyEntityToMyEntityDto2Mapper : IObjectMapper<MyEntity, MyEntityDto2>, IObjectMapper<MyEntityDto2, MyEntity>, ITransientDependency |
||||
|
{ |
||||
|
public MyEntityDto2 Map(MyEntity source) |
||||
|
{ |
||||
|
return new MyEntityDto2 |
||||
|
{ |
||||
|
Id = source.Id, |
||||
|
Number = source.Number + 1 |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public MyEntityDto2 Map(MyEntity source, MyEntityDto2 destination) |
||||
|
{ |
||||
|
destination.Id = source.Id; |
||||
|
destination.Number = source.Number + 1; |
||||
|
return destination; |
||||
|
} |
||||
|
|
||||
|
public MyEntity Map(MyEntityDto2 source) |
||||
|
{ |
||||
|
return new MyEntity |
||||
|
{ |
||||
|
Id = source.Id, |
||||
|
Number = source.Number + 1 |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public MyEntity Map(MyEntityDto2 source, MyEntity destination) |
||||
|
{ |
||||
|
destination.Id = source.Id; |
||||
|
destination.Number = source.Number + 1; |
||||
|
return destination; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
namespace Volo.Abp.Mapperly.SampleClasses; |
||||
|
|
||||
|
public enum MyEnum |
||||
|
{ |
||||
|
Value1 = 1, |
||||
|
Value2, |
||||
|
Value3 |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
namespace Volo.Abp.Mapperly.SampleClasses; |
||||
|
|
||||
|
public enum MyEnumDto |
||||
|
{ |
||||
|
Value1 = 2, |
||||
|
Value2, |
||||
|
Value3, |
||||
|
Value |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
using System; |
||||
|
|
||||
|
namespace Volo.Abp.Mapperly.SampleClasses; |
||||
|
|
||||
|
public class MyNotMappedDto |
||||
|
{ |
||||
|
public Guid Id { get; set; } |
||||
|
|
||||
|
public int Number { get; set; } |
||||
|
} |
||||
Loading…
Reference in new issue