Browse Source

Remove `IMapperAccessor`.

Resolve #14766

Register `IMapper` as transient, `MapperConfiguration` as `singleton`.
pull/14778/head
maliming 4 years ago
parent
commit
1762c8aa99
No known key found for this signature in database GPG Key ID: 96224957E51C89E
  1. 1
      framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperConfigurationContext.cs
  2. 46
      framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs
  3. 24
      framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AutoMapperAutoObjectMappingProvider.cs
  4. 8
      framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/IMapperAccessor.cs
  5. 8
      framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/MapperAccessor.cs
  6. 2
      framework/src/Volo.Abp.AutoMapper/Volo/Abp/ObjectMapping/AbpAutoMapperObjectMapperExtensions.cs
  7. 5
      framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapper_CustomServiceConstruction_Tests.cs
  8. 27
      framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapper_Dependency_Injection_Tests.cs

1
framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperConfigurationContext.cs

@ -6,6 +6,7 @@ namespace Volo.Abp.AutoMapper;
public class AbpAutoMapperConfigurationContext : IAbpAutoMapperConfigurationContext public class AbpAutoMapperConfigurationContext : IAbpAutoMapperConfigurationContext
{ {
public IMapperConfigurationExpression MapperConfiguration { get; } public IMapperConfigurationExpression MapperConfiguration { get; }
public IServiceProvider ServiceProvider { get; } public IServiceProvider ServiceProvider { get; }
public AbpAutoMapperConfigurationContext( public AbpAutoMapperConfigurationContext(

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

@ -26,45 +26,31 @@ public class AbpAutoMapperModule : AbpModule
{ {
context.Services.AddAutoMapperObjectMapper(); context.Services.AddAutoMapperObjectMapper();
context.Services.AddSingleton<MapperAccessor>(CreateMappings); context.Services.AddSingleton<IConfigurationProvider>(sp =>
context.Services.AddSingleton<IMapperAccessor>(provider => provider.GetRequiredService<MapperAccessor>());
}
private MapperAccessor CreateMappings(IServiceProvider serviceProvider)
{
using (var scope = serviceProvider.CreateScope())
{ {
var options = scope.ServiceProvider.GetRequiredService<IOptions<AbpAutoMapperOptions>>().Value; using (var scope = sp.CreateScope())
void ConfigureAll(IAbpAutoMapperConfigurationContext ctx)
{ {
foreach (var configurator in options.Configurators) var options = scope.ServiceProvider.GetRequiredService<IOptions<AbpAutoMapperOptions>>().Value;
var mapperConfiguration = new MapperConfiguration(mapperConfigurationExpression =>
{ {
configurator(ctx); var autoMapperConfigurationContext = new AbpAutoMapperConfigurationContext(mapperConfigurationExpression, scope.ServiceProvider);
}
}
options.Configurators.Insert(0, ctx => ctx.MapperConfiguration.ConstructServicesUsing(serviceProvider.GetService)); foreach (var configurator in options.Configurators)
{
configurator(autoMapperConfigurationContext);
}
});
void ValidateAll(IConfigurationProvider config)
{
foreach (var profileType in options.ValidatingProfiles) foreach (var profileType in options.ValidatingProfiles)
{ {
config.Internal().AssertConfigurationIsValid(((Profile)Activator.CreateInstance(profileType)).ProfileName); mapperConfiguration.Internal().AssertConfigurationIsValid(((Profile)Activator.CreateInstance(profileType)).ProfileName);
} }
}
var mapperConfiguration = new MapperConfiguration(mapperConfigurationExpression =>
{
ConfigureAll(new AbpAutoMapperConfigurationContext(mapperConfigurationExpression, scope.ServiceProvider));
});
ValidateAll(mapperConfiguration); return mapperConfiguration;
}
});
return new MapperAccessor context.Services.AddTransient<IMapper>(sp => sp.GetRequiredService<IConfigurationProvider>().CreateMapper(sp.GetService));
{
Mapper = new Mapper(mapperConfiguration)
};
}
} }
} }

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

@ -1,31 +1,37 @@
using Volo.Abp.ObjectMapping; using System;
using AutoMapper;
using Volo.Abp.ObjectMapping;
namespace Volo.Abp.AutoMapper; namespace Volo.Abp.AutoMapper;
public class AutoMapperAutoObjectMappingProvider<TContext> : AutoMapperAutoObjectMappingProvider, IAutoObjectMappingProvider<TContext> public class AutoMapperAutoObjectMappingProvider<TContext> : AutoMapperAutoObjectMappingProvider, IAutoObjectMappingProvider<TContext>
{ {
public AutoMapperAutoObjectMappingProvider(IMapperAccessor mapperAccessor) public AutoMapperAutoObjectMappingProvider(IMapper mapper)
: base(mapperAccessor) : base(mapper)
{ {
} }
} }
public class AutoMapperAutoObjectMappingProvider : IAutoObjectMappingProvider public class AutoMapperAutoObjectMappingProvider : IAutoObjectMappingProvider, IDisposable
{ {
public IMapperAccessor MapperAccessor { get; } public IMapper Mapper { get; }
public AutoMapperAutoObjectMappingProvider(IMapperAccessor mapperAccessor) public AutoMapperAutoObjectMappingProvider(IMapper mapper)
{ {
MapperAccessor = mapperAccessor; Mapper = mapper;
} }
public virtual TDestination Map<TSource, TDestination>(object source) public virtual TDestination Map<TSource, TDestination>(object source)
{ {
return MapperAccessor.Mapper.Map<TDestination>(source); return Mapper.Map<TDestination>(source);
} }
public virtual TDestination Map<TSource, TDestination>(TSource source, TDestination destination) public virtual TDestination Map<TSource, TDestination>(TSource source, TDestination destination)
{ {
return MapperAccessor.Mapper.Map(source, destination); return Mapper.Map(source, destination);
}
public void Dispose()
{
} }
} }

8
framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/IMapperAccessor.cs

@ -1,8 +0,0 @@
using AutoMapper;
namespace Volo.Abp.AutoMapper;
public interface IMapperAccessor
{
IMapper Mapper { get; }
}

8
framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/MapperAccessor.cs

@ -1,8 +0,0 @@
using AutoMapper;
namespace Volo.Abp.AutoMapper;
internal class MapperAccessor : IMapperAccessor
{
public IMapper Mapper { get; set; }
}

2
framework/src/Volo.Abp.AutoMapper/Volo/Abp/ObjectMapping/AbpAutoMapperObjectMapperExtensions.cs

@ -14,7 +14,7 @@ public static class AbpAutoMapperObjectMapperExtensions
{ {
if (autoObjectMappingProvider is AutoMapperAutoObjectMappingProvider autoMapperAutoObjectMappingProvider) if (autoObjectMappingProvider is AutoMapperAutoObjectMappingProvider autoMapperAutoObjectMappingProvider)
{ {
return autoMapperAutoObjectMappingProvider.MapperAccessor.Mapper; return autoMapperAutoObjectMappingProvider.Mapper;
} }
throw new AbpException($"Given object is not an instance of {typeof(AutoMapperAutoObjectMappingProvider).AssemblyQualifiedName}. The type of the given object it {autoObjectMappingProvider.GetType().AssemblyQualifiedName}"); throw new AbpException($"Given object is not an instance of {typeof(AutoMapperAutoObjectMappingProvider).AssemblyQualifiedName}. The type of the given object it {autoObjectMappingProvider.GetType().AssemblyQualifiedName}");

5
framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapper_CustomServiceConstruction_Tests.cs

@ -1,6 +1,7 @@
using System; using System;
using AutoMapper; using AutoMapper;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Shouldly; using Shouldly;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.Testing; using Volo.Abp.Testing;
@ -25,6 +26,7 @@ public class AutoMapper_CustomServiceConstruction_Tests : AbpIntegratedTest<Auto
{ {
Name = nameof(SourceModel) Name = nameof(SourceModel)
}; };
_objectMapper.Map<SourceModel, DestModel>(source).Name.ShouldBe(nameof(CustomMappingAction)); _objectMapper.Map<SourceModel, DestModel>(source).Name.ShouldBe(nameof(CustomMappingAction));
} }
@ -33,6 +35,9 @@ public class AutoMapper_CustomServiceConstruction_Tests : AbpIntegratedTest<Auto
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
{ {
// Replace the build-in IMapper with a custom one to use ConstructServicesUsing.
context.Services.Replace(ServiceDescriptor.Transient<IMapper>(sp => sp.GetRequiredService<IConfigurationProvider>().CreateMapper()));
Configure<AbpAutoMapperOptions>(options => Configure<AbpAutoMapperOptions>(options =>
{ {
options.AddMaps<TestModule>(); options.AddMaps<TestModule>();

27
framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AutoMapper_Dependency_Injection_Tests.cs

@ -1,4 +1,6 @@
using AutoMapper; using System;
using AutoMapper;
using Microsoft.Extensions.DependencyInjection;
using Shouldly; using Shouldly;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Testing; using Volo.Abp.Testing;
@ -9,13 +11,6 @@ namespace Volo.Abp.AutoMapper;
public class AutoMapper_Dependency_Injection_Tests : AbpIntegratedTest<AutoMapperTestModule> public class AutoMapper_Dependency_Injection_Tests : AbpIntegratedTest<AutoMapperTestModule>
{ {
private readonly IObjectMapper _objectMapper;
public AutoMapper_Dependency_Injection_Tests()
{
_objectMapper = GetRequiredService<IObjectMapper>();
}
[Fact] [Fact]
public void Should_Registered_AutoMapper_Service() public void Should_Registered_AutoMapper_Service()
{ {
@ -30,7 +25,12 @@ public class AutoMapper_Dependency_Injection_Tests : AbpIntegratedTest<AutoMappe
Name = "Source" Name = "Source"
}; };
_objectMapper.Map<SourceModel, DestModel>(sourceModel).Name.ShouldBe(nameof(CustomMappingActionService)); using (var scope = ServiceProvider.CreateScope())
{
scope.ServiceProvider.GetRequiredService<IObjectMapper>().Map<SourceModel, DestModel>(sourceModel).Name.ShouldBe(nameof(CustomMappingActionService));
}
CustomMappingAction.IsDisposed.ShouldBeTrue();
} }
public class SourceModel public class SourceModel
@ -51,8 +51,10 @@ public class AutoMapper_Dependency_Injection_Tests : AbpIntegratedTest<AutoMappe
} }
} }
public class CustomMappingAction : IMappingAction<SourceModel, DestModel> public class CustomMappingAction : IMappingAction<SourceModel, DestModel>, IDisposable
{ {
public static bool IsDisposed = false;
private readonly CustomMappingActionService _customMappingActionService; private readonly CustomMappingActionService _customMappingActionService;
public CustomMappingAction(CustomMappingActionService customMappingActionService) public CustomMappingAction(CustomMappingActionService customMappingActionService)
@ -64,6 +66,11 @@ public class AutoMapper_Dependency_Injection_Tests : AbpIntegratedTest<AutoMappe
{ {
destination.Name = _customMappingActionService.GetName(); destination.Name = _customMappingActionService.GetName();
} }
public void Dispose()
{
IsDisposed = true;
}
} }
public class CustomMappingActionService : ITransientDependency public class CustomMappingActionService : ITransientDependency

Loading…
Cancel
Save