mirror of https://github.com/abpframework/abp.git
9 changed files with 156 additions and 38 deletions
@ -0,0 +1,68 @@ |
|||||
|
using System; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.ObjectMapping |
||||
|
{ |
||||
|
//TODO: It can be slow to always check if service is available. Test it and optimize if necessary.
|
||||
|
|
||||
|
public class DefaultObjectMapper : IObjectMapper, ISingletonDependency |
||||
|
{ |
||||
|
private readonly IServiceProvider _serviceProvider; |
||||
|
|
||||
|
public DefaultObjectMapper(IServiceProvider serviceProvider) |
||||
|
{ |
||||
|
_serviceProvider = serviceProvider; |
||||
|
} |
||||
|
|
||||
|
public virtual TDestination Map<TSource, TDestination>(TSource source) |
||||
|
{ |
||||
|
if (source == null) |
||||
|
{ |
||||
|
return default(TDestination); |
||||
|
} |
||||
|
|
||||
|
//Check if a specific mapper is registered
|
||||
|
using (var scope = _serviceProvider.CreateScope()) |
||||
|
{ |
||||
|
var specificMapper = scope.ServiceProvider.GetService<IObjectMapper<TSource, TDestination>>(); |
||||
|
if (specificMapper != null) |
||||
|
{ |
||||
|
return specificMapper.Map(source); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return AutoMap<TSource, TDestination>(source); |
||||
|
} |
||||
|
|
||||
|
public virtual TDestination Map<TSource, TDestination>(TSource source, TDestination destination) |
||||
|
{ |
||||
|
if (source == null) |
||||
|
{ |
||||
|
return default(TDestination); |
||||
|
} |
||||
|
|
||||
|
//Check if a specific mapper is registered
|
||||
|
using (var scope = _serviceProvider.CreateScope()) |
||||
|
{ |
||||
|
var specificMapper = scope.ServiceProvider.GetService<IObjectMapper<TSource, TDestination>>(); |
||||
|
if (specificMapper != null) |
||||
|
{ |
||||
|
return specificMapper.Map(source, destination); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return AutoMap(source, destination); |
||||
|
} |
||||
|
|
||||
|
protected virtual TDestination AutoMap<TSource, TDestination>(object source) |
||||
|
{ |
||||
|
throw new NotImplementedException($"Can not map from given object ({source}) to {typeof(TDestination).AssemblyQualifiedName}."); |
||||
|
} |
||||
|
|
||||
|
protected virtual TDestination AutoMap<TSource, TDestination>(TSource source, TDestination destination) |
||||
|
{ |
||||
|
throw new NotImplementedException($"Can no map from {typeof(TSource).AssemblyQualifiedName} to {typeof(TDestination).AssemblyQualifiedName}."); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,23 +0,0 @@ |
|||||
using System; |
|
||||
using Volo.DependencyInjection; |
|
||||
|
|
||||
namespace Volo.Abp.ObjectMapping |
|
||||
{ |
|
||||
public sealed class NotImplementedObjectMapper : IObjectMapper, ISingletonDependency |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Singleton instance.
|
|
||||
/// </summary>
|
|
||||
public static NotImplementedObjectMapper Instance { get; } = new NotImplementedObjectMapper(); |
|
||||
|
|
||||
public TDestination Map<TDestination>(object source) |
|
||||
{ |
|
||||
throw new NotImplementedException("Abp.ObjectMapping.IObjectMapper should be implemented in order to map objects."); |
|
||||
} |
|
||||
|
|
||||
public TDestination Map<TSource, TDestination>(TSource source, TDestination destination) |
|
||||
{ |
|
||||
throw new NotImplementedException("Abp.ObjectMapping.IObjectMapper should be implemented in order to map objects."); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,26 @@ |
|||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Shouldly; |
||||
|
using Volo.Abp.AutoMapper.SampleClasses; |
||||
|
using Volo.Abp.ObjectMapping; |
||||
|
using Volo.Abp.TestBase; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.AutoMapper |
||||
|
{ |
||||
|
public class AbpAutoMapperModule_Specific_ObjectMapper_Tests : AbpIntegratedTest<AutoMapperTestModule> |
||||
|
{ |
||||
|
private readonly IObjectMapper _objectMapper; |
||||
|
|
||||
|
public AbpAutoMapperModule_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.
|
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
using Volo.Abp.Application.Services.Dtos; |
||||
|
|
||||
|
namespace Volo.Abp.AutoMapper.SampleClasses |
||||
|
{ |
||||
|
public class MyEntityDto2 : EntityDto |
||||
|
{ |
||||
|
public int Number { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
using Volo.Abp.ObjectMapping; |
||||
|
using Volo.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.AutoMapper.SampleClasses |
||||
|
{ |
||||
|
[ExposeServices(typeof(IObjectMapper<MyEntity, MyEntityDto2>))] |
||||
|
public class MyEntityToMyEntityDto2Mapper : IObjectMapper<MyEntity, MyEntityDto2>, 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; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue