diff --git a/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs b/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs index f1e266b745..71dd37d259 100644 --- a/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs +++ b/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperModule.cs @@ -40,6 +40,17 @@ public class AbpAutoMapperModule : AbpModule configurator(autoMapperConfigurationContext); } + if (options.DefaultMaxDepth.HasValue) + { + mapperConfigurationExpression.Internal().ForAllMaps((typeMap, _) => + { + if (typeMap.MaxDepth == 0) + { + typeMap.MaxDepth = options.DefaultMaxDepth.Value; + } + }); + } + var mapperConfiguration = new MapperConfiguration(mapperConfigurationExpression); foreach (var profileType in options.ValidatingProfiles) diff --git a/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperOptions.cs b/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperOptions.cs index e5cf1a0556..f6ab5a5408 100644 --- a/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperOptions.cs +++ b/framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperOptions.cs @@ -12,6 +12,13 @@ public class AbpAutoMapperOptions public ITypeList ValidatingProfiles { get; set; } + /// + /// Default MaxDepth applied to all maps that don't have an explicit MaxDepth configured. + /// Set to null to disable the default MaxDepth behavior. + /// Default: 64. + /// + public int? DefaultMaxDepth { get; set; } = 64; + public AbpAutoMapperOptions() { Configurators = new List>(); diff --git a/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_MaxDepth_Tests.cs b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_MaxDepth_Tests.cs new file mode 100644 index 0000000000..d7cf32913b --- /dev/null +++ b/framework/test/Volo.Abp.AutoMapper.Tests/Volo/Abp/AutoMapper/AbpAutoMapperModule_MaxDepth_Tests.cs @@ -0,0 +1,102 @@ +using AutoMapper; +using AutoMapper.Internal; +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using Volo.Abp.AutoMapper.SampleClasses; +using Volo.Abp.Modularity; +using Volo.Abp.ObjectExtending; +using Volo.Abp.Testing; +using Xunit; + +namespace Volo.Abp.AutoMapper; + +public class AbpAutoMapperModule_MaxDepth_Tests : AbpIntegratedTest +{ + private readonly IConfigurationProvider _configurationProvider; + + public AbpAutoMapperModule_MaxDepth_Tests() + { + _configurationProvider = ServiceProvider.GetRequiredService(); + } + + [Fact] + public void Should_Set_Default_MaxDepth_For_All_Maps() + { + var typeMap = _configurationProvider.Internal().FindTypeMapFor(); + typeMap.ShouldNotBeNull(); + typeMap.MaxDepth.ShouldBe(64); + } +} + +public class AbpAutoMapperModule_CustomMaxDepth_Tests : AbpIntegratedTest +{ + private readonly IConfigurationProvider _configurationProvider; + + public AbpAutoMapperModule_CustomMaxDepth_Tests() + { + _configurationProvider = ServiceProvider.GetRequiredService(); + } + + [Fact] + public void Should_Not_Override_Custom_MaxDepth() + { + var typeMap = _configurationProvider.Internal().FindTypeMapFor(); + typeMap.ShouldNotBeNull(); + typeMap.MaxDepth.ShouldBe(10); + } + + [DependsOn( + typeof(AbpAutoMapperModule), + typeof(AbpObjectExtendingTestModule) + )] + public class TestModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Configurators.Add(ctx => + { + ctx.MapperConfiguration.CreateMap().MaxDepth(10); + }); + }); + } + } +} + +public class AbpAutoMapperModule_DisabledMaxDepth_Tests : AbpIntegratedTest +{ + private readonly IConfigurationProvider _configurationProvider; + + public AbpAutoMapperModule_DisabledMaxDepth_Tests() + { + _configurationProvider = ServiceProvider.GetRequiredService(); + } + + [Fact] + public void Should_Not_Set_MaxDepth_When_Disabled() + { + var typeMap = _configurationProvider.Internal().FindTypeMapFor(); + typeMap.ShouldNotBeNull(); + typeMap.MaxDepth.ShouldBe(0); + } + + [DependsOn( + typeof(AbpAutoMapperModule), + typeof(AbpObjectExtendingTestModule) + )] + public class TestModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.DefaultMaxDepth = null; + options.Configurators.Add(ctx => + { + ctx.MapperConfiguration.CreateMap(); + }); + }); + } + } +}