Browse Source

Resolved #1706: Remove ABP's AutoMap attributes.

pull/1710/head
Halil İbrahim Kalkan 7 years ago
parent
commit
a48857f394
  1. 29
      framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapAttribute.cs
  2. 17
      framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapAttributeBase.cs
  3. 36
      framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapFromAttribute.cs
  4. 36
      framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapToAttribute.cs
  5. 36
      framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs
  6. 17
      framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapperConfigurationExtensions.cs
  7. 5
      framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapperTestModule.cs
  8. 75
      framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapper_Inheritance_Tests.cs
  9. 157
      framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapping_Tests.cs
  10. 1
      framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/SampleClasses/MyEntityDto.cs
  11. 12
      framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/SampleClasses/MyMapProfile.cs
  12. 2
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/Person.cs
  13. 12
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/TestAutoMapProfile.cs
  14. 2
      framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs

29
framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapAttribute.cs

@ -1,29 +0,0 @@
using System;
using System.Collections.Generic;
using AutoMapper;
namespace Volo.Abp.AutoMapper
{
public class AbpAutoMapAttribute : AbpAutoMapAttributeBase
{
public AbpAutoMapAttribute(params Type[] targetTypes)
: base(targetTypes)
{
}
public override void CreateMap(IMapperConfigurationExpression configuration, Type type)
{
if (TargetTypes.IsNullOrEmpty())
{
return;
}
foreach (var targetType in TargetTypes)
{
configuration.CreateMap(type, targetType, MemberList.Source);
configuration.CreateMap(targetType, type, MemberList.Destination);
}
}
}
}

17
framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapAttributeBase.cs

@ -1,17 +0,0 @@
using System;
using AutoMapper;
namespace Volo.Abp.AutoMapper
{
public abstract class AbpAutoMapAttributeBase : Attribute
{
public Type[] TargetTypes { get; }
protected AbpAutoMapAttributeBase(params Type[] targetTypes)
{
TargetTypes = targetTypes;
}
public abstract void CreateMap(IMapperConfigurationExpression configuration, Type type);
}
}

36
framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapFromAttribute.cs

@ -1,36 +0,0 @@
using System;
using System.Collections.Generic;
using AutoMapper;
namespace Volo.Abp.AutoMapper
{
public class AbpAutoMapFromAttribute : AbpAutoMapAttributeBase
{
public MemberList MemberList { get; set; } = MemberList.Destination;
public AbpAutoMapFromAttribute(params Type[] targetTypes)
: base(targetTypes)
{
}
public AbpAutoMapFromAttribute(MemberList memberList, params Type[] targetTypes)
: this(targetTypes)
{
MemberList = memberList;
}
public override void CreateMap(IMapperConfigurationExpression configuration, Type type)
{
if (TargetTypes.IsNullOrEmpty())
{
return;
}
foreach (var targetType in TargetTypes)
{
configuration.CreateMap(targetType, type, MemberList);
}
}
}
}

36
framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapToAttribute.cs

@ -1,36 +0,0 @@
using System;
using System.Collections.Generic;
using AutoMapper;
namespace Volo.Abp.AutoMapper
{
public class AbpAutoMapToAttribute : AbpAutoMapAttributeBase
{
public MemberList MemberList { get; set; } = MemberList.Source;
public AbpAutoMapToAttribute(params Type[] targetTypes)
: base(targetTypes)
{
}
public AbpAutoMapToAttribute(MemberList memberList, params Type[] targetTypes)
: this(targetTypes)
{
MemberList = memberList;
}
public override void CreateMap(IMapperConfigurationExpression configuration, Type type)
{
if (TargetTypes.IsNullOrEmpty())
{
return;
}
foreach (var targetType in TargetTypes)
{
configuration.CreateMap(type, targetType, MemberList);
}
}
}
}

36
framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs

@ -1,13 +1,9 @@
using System;
using System.Linq;
using System.Reflection;
using AutoMapper;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Volo.Abp.Modularity;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Reflection;
namespace Volo.Abp.AutoMapper
{
@ -34,7 +30,6 @@ namespace Volo.Abp.AutoMapper
void ConfigureAll(IAbpAutoMapperConfigurationContext ctx)
{
FindAndAutoMapTypes(ctx);
foreach (var configurator in options.Configurators)
{
configurator(ctx);
@ -59,36 +54,5 @@ namespace Volo.Abp.AutoMapper
scope.ServiceProvider.GetRequiredService<MapperAccessor>().Mapper = mapperConfiguration.CreateMapper();
}
}
private void FindAndAutoMapTypes(IAbpAutoMapperConfigurationContext context)
{
//TODO: AutoMapping (by attributes) can be optionally enabled/disabled.
var typeFinder = context.ServiceProvider.GetRequiredService<ITypeFinder>();
var logger = context.ServiceProvider.GetRequiredService<ILogger<AbpAutoMapperModule>>();
var types = typeFinder.Types.Where(type =>
{
var typeInfo = type.GetTypeInfo();
return typeInfo.IsDefined(typeof(AbpAutoMapAttribute)) ||
typeInfo.IsDefined(typeof(AbpAutoMapFromAttribute)) ||
typeInfo.IsDefined(typeof(AbpAutoMapToAttribute));
}
).ToArray();
if (types.Length <= 0)
{
logger.LogDebug($"No class found with auto mapping attributes.");
}
else
{
logger.LogDebug($"Found {types.Length} classes define auto mapping attributes.");
foreach (var type in types)
{
logger.LogDebug(type.FullName);
context.MapperConfiguration.CreateAutoAttributeMaps(type);
}
}
}
}
}

17
framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapperConfigurationExtensions.cs

@ -1,17 +0,0 @@
using System;
using System.Reflection;
using AutoMapper;
namespace Volo.Abp.AutoMapper
{
internal static class AutoMapperConfigurationExtensions
{
public static void CreateAutoAttributeMaps(this IMapperConfigurationExpression configuration, Type type)
{
foreach (var autoMapAttribute in type.GetTypeInfo().GetCustomAttributes<AbpAutoMapAttributeBase>())
{
autoMapAttribute.CreateMap(configuration, type);
}
}
}
}

5
framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutofacTestModule.cs → framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapperTestModule.cs

@ -8,7 +8,10 @@ namespace Volo.Abp.AutoMapper
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAutoMapperOptions>(options =>
{
options.AddMaps<AutoMapperTestModule>();
});
}
}
}

75
framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapper_Inheritance_Tests.cs

@ -1,75 +0,0 @@
using AutoMapper;
using Shouldly;
using Xunit;
namespace Volo.Abp.AutoMapper
{
public class AutoMapper_Inheritance_Tests
{
private readonly IMapper _mapper;
public AutoMapper_Inheritance_Tests()
{
var config = new MapperConfiguration(configuration =>
{
configuration.CreateAutoAttributeMaps(typeof(MyTargetClassToMap));
configuration.CreateAutoAttributeMaps(typeof(EntityDto));
configuration.CreateAutoAttributeMaps(typeof(DerivedEntityDto));
});
_mapper = config.CreateMapper();
}
[Fact]
public void Should_Map_Derived_To_Target()
{
var derived = new MyDerivedClass { Value = "fortytwo" };
var target = _mapper.Map<MyTargetClassToMap>(derived);
target.Value.ShouldBe("fortytwo");
}
public class MyBaseClass
{
public string Value { get; set; }
}
public class MyDerivedClass : MyBaseClass
{
}
[AbpAutoMapFrom(typeof(MyBaseClass))]
public class MyTargetClassToMap
{
public string Value { get; set; }
}
//[Fact] //TODO: That's a problem but related to AutoMapper rather than ABP.
public void Should_Map_EntityProxy_To_EntityDto_And_To_DrivedEntityDto()
{
var proxy = new EntityProxy() { Value = "42"};
var target = _mapper.Map<EntityDto>(proxy);
var target2 = _mapper.Map<DerivedEntityDto>(proxy);
target.Value.ShouldBe("42");
target2.Value.ShouldBe("42");
}
private class Entity
{
public string Value { get; set; }
}
private class DerivedEntity : Entity { }
private class EntityProxy : DerivedEntity { }
[AbpAutoMapFrom(typeof(Entity))]
private class EntityDto
{
public string Value { get; set; }
}
[AbpAutoMapFrom(typeof(DerivedEntity))]
private class DerivedEntityDto : EntityDto { }
}
}

157
framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapping_Tests.cs

@ -1,157 +0,0 @@
using System;
using System.Collections.Generic;
using AutoMapper;
using Shouldly;
using Xunit;
namespace Volo.Abp.AutoMapper
{
public class AutoMapping_Tests
{
private readonly IMapper _mapper;
public AutoMapping_Tests()
{
var config = new MapperConfiguration(configuration =>
{
configuration.CreateAutoAttributeMaps(typeof(MyClass1));
configuration.CreateAutoAttributeMaps(typeof(MyClass2));
});
_mapper = config.CreateMapper();
}
[Fact]
public void Map_Null_Tests()
{
MyClass1 obj1 = null;
var obj2 = _mapper.Map<MyClass2>(obj1);
obj2.ShouldBe(null);
}
[Fact]
public void Map_Null_Existing_Object_Tests()
{
MyClass1 obj1 = null;
var obj2 = new MyClass2 { TestProp = "before map" };
_mapper.Map(obj1, obj2);
obj2.TestProp.ShouldBe("before map");
}
[Fact]
public void MapTo_Tests()
{
var obj1 = new MyClass1 { TestProp = "Test value" };
var obj2 = _mapper.Map<MyClass2>(obj1);
obj2.TestProp.ShouldBe("Test value");
var obj3 = _mapper.Map<MyClass3>(obj1);
obj3.TestProp.ShouldBe("Test value");
}
[Fact]
public void MapTo_Existing_Object_Tests()
{
var obj1 = new MyClass1 { TestProp = "Test value" };
var obj2 = new MyClass2();
_mapper.Map(obj1, obj2);
obj2.TestProp.ShouldBe("Test value");
var obj3 = new MyClass3();
_mapper.Map(obj2, obj3);
obj3.TestProp.ShouldBe("Test value");
Assert.ThrowsAny<Exception>(() => //Did not define reverse mapping!
{
_mapper.Map(obj3, obj2);
});
}
[Fact]
public void MapFrom_Tests()
{
var obj2 = new MyClass2 { TestProp = "Test value" };
var obj1 = _mapper.Map<MyClass1>(obj2);
obj1.TestProp.ShouldBe("Test value");
}
[Fact]
public void IgnoreMap_Tests()
{
var obj2 = new MyClass2 {TestProp = "Test value", AnotherValue = 42};
var obj3 = _mapper.Map<MyClass3>(obj2);
obj3.TestProp.ShouldBe("Test value");
obj3.AnotherValue.ShouldBe(0); //Ignored because of IgnoreMap attribute!
}
[Fact]
public void MapTo_Collection_Tests()
{
var list1 = new List<MyClass1>
{
new MyClass1 {TestProp = "Test value 1"},
new MyClass1 {TestProp = "Test value 2"}
};
var list2 = _mapper.Map<List<MyClass2>>(list1);
list2.Count.ShouldBe(2);
list2[0].TestProp.ShouldBe("Test value 1");
list2[1].TestProp.ShouldBe("Test value 2");
}
[Fact]
public void Map_Should_Set_Null_Existing_Object_Tests()
{
MyClass1 obj1 = new MyClass1 { TestProp = null };
var obj2 = new MyClass2 { TestProp = "before map" };
_mapper.Map(obj1, obj2);
obj2.TestProp.ShouldBe(null);
}
[Fact]
public void Should_Map_Nullable_Value_To_Null_If_It_Is_Null_On_Source()
{
var obj1 = new MyClass1();
var obj2 = _mapper.Map<MyClass2>(obj1);
obj2.NullableValue.ShouldBeNull();
}
[Fact]
public void Should_Map_Nullable_Value_To__Not_Null_If_It_Is__Not_Null_On_Source()
{
var obj1 = new MyClass1 { NullableValue = 42 };
var obj2 = _mapper.Map<MyClass2>(obj1);
obj2.NullableValue.ShouldBe(42);
}
[AbpAutoMap(typeof(MyClass2), typeof(MyClass3))]
private class MyClass1
{
public string TestProp { get; set; }
public long? NullableValue { get; set; }
}
[AbpAutoMapTo(typeof(MyClass3))]
private class MyClass2
{
public string TestProp { get; set; }
public long? NullableValue { get; set; }
public int AnotherValue { get; set; }
}
private class MyClass3
{
public string TestProp { get; set; }
[IgnoreMap]
public int AnotherValue { get; set; }
}
}
}

1
framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/SampleClasses/MyEntityDto.cs

@ -2,7 +2,6 @@
namespace Volo.Abp.AutoMapper.SampleClasses
{
[AbpAutoMap(typeof(MyEntity))]
public class MyEntityDto
{
public Guid Id { get; set; }

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

@ -0,0 +1,12 @@
using AutoMapper;
namespace Volo.Abp.AutoMapper.SampleClasses
{
public class MyMapProfile : Profile
{
public MyMapProfile()
{
CreateMap<MyEntity, MyEntityDto>().ReverseMap();
}
}
}

2
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/Person.cs

@ -1,12 +1,10 @@
using System;
using System.Collections.ObjectModel;
using Volo.Abp.AutoMapper;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.TestApp.Domain
{
[AbpAutoMapTo(typeof(PersonEto))]
public class Person : FullAuditedAggregateRoot<Guid>, IMultiTenant
{
public virtual Guid? TenantId { get; set; }

12
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/TestAutoMapProfile.cs

@ -0,0 +1,12 @@
using AutoMapper;
namespace Volo.Abp.TestApp.Domain
{
public class TestAutoMapProfile : Profile
{
public TestAutoMapProfile()
{
CreateMap<PersonEto, Person>().ReverseMap();
}
}
}

2
framework/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs

@ -37,6 +37,8 @@ namespace Volo.Abp.TestApp
ctx.MapperConfiguration.CreateMap<Person, PersonDto>().ReverseMap();
ctx.MapperConfiguration.CreateMap<Phone, PhoneDto>().ReverseMap();
});
options.AddMaps<TestAppModule>();
});
}

Loading…
Cancel
Save