From 0a140bfe3ef5c8d1f52649133afd45378aeffbbd Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 17 Mar 2023 09:56:50 +0800 Subject: [PATCH 1/3] Avoid cache scoped DI containers in Lazy object. Resolve #15987 --- .../AbpAspNetCoreMvcNewtonsoftModule.cs | 7 ++++--- ...bpCamelCasePropertyNamesContractResolver.cs | 18 ++++++------------ .../Newtonsoft/AbpDefaultContractResolver.cs | 13 ++++--------- .../Json/Newtonsoft/AbpJsonNewtonsoftModule.cs | 7 ++++--- .../Newtonsoft/AbpNewtonsoftJsonSerializer.cs | 10 ++++++---- .../AbpDefaultJsonTypeInfoResolver.cs | 3 +-- 6 files changed, 25 insertions(+), 33 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs index 6e71fe7b5f..4ee0f6c831 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Mvc; +using System; +using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Json.Newtonsoft; using Volo.Abp.Modularity; @@ -13,9 +14,9 @@ public class AbpAspNetCoreMvcNewtonsoftModule : AbpModule context.Services.AddMvcCore().AddNewtonsoftJson(); context.Services.AddOptions() - .Configure((options, contractResolver) => + .Configure((options, serviceProvider) => { - options.SerializerSettings.ContractResolver = contractResolver; + options.SerializerSettings.ContractResolver = new AbpCamelCasePropertyNamesContractResolver(serviceProvider.GetRequiredService()); }); } } diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpCamelCasePropertyNamesContractResolver.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpCamelCasePropertyNamesContractResolver.cs index 3e4e5d0121..aabb1e6b10 100644 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpCamelCasePropertyNamesContractResolver.cs +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpCamelCasePropertyNamesContractResolver.cs @@ -1,22 +1,16 @@ -using System; -using System.Reflection; -using Microsoft.Extensions.DependencyInjection; +using System.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; -using Volo.Abp.DependencyInjection; namespace Volo.Abp.Json.Newtonsoft; -public class AbpCamelCasePropertyNamesContractResolver : CamelCasePropertyNamesContractResolver, ITransientDependency +public class AbpCamelCasePropertyNamesContractResolver : CamelCasePropertyNamesContractResolver { - private readonly Lazy _dateTimeConverter; + private readonly AbpDateTimeConverter _dateTimeConverter; - public AbpCamelCasePropertyNamesContractResolver(IServiceProvider serviceProvider) + public AbpCamelCasePropertyNamesContractResolver(AbpDateTimeConverter dateTimeConverter) { - _dateTimeConverter = new Lazy( - serviceProvider.GetRequiredService, - true - ); + _dateTimeConverter = dateTimeConverter; NamingStrategy = new CamelCaseNamingStrategy { @@ -30,7 +24,7 @@ public class AbpCamelCasePropertyNamesContractResolver : CamelCasePropertyNamesC if (AbpDateTimeConverter.ShouldNormalize(member, property)) { - property.Converter = _dateTimeConverter.Value; + property.Converter = _dateTimeConverter; } return property; diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs index 131e95d4c2..527a7282e6 100644 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs @@ -1,6 +1,4 @@ -using System; using System.Reflection; -using Microsoft.Extensions.DependencyInjection; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using Volo.Abp.DependencyInjection; @@ -9,14 +7,11 @@ namespace Volo.Abp.Json.Newtonsoft; public class AbpDefaultContractResolver : DefaultContractResolver, ITransientDependency { - private readonly Lazy _dateTimeConverter; + private readonly AbpDateTimeConverter _dateTimeConverter; - public AbpDefaultContractResolver(IServiceProvider serviceProvider) + public AbpDefaultContractResolver(AbpDateTimeConverter dateTimeConverter) { - _dateTimeConverter = new Lazy( - serviceProvider.GetRequiredService, - true - ); + _dateTimeConverter = dateTimeConverter; } protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) @@ -25,7 +20,7 @@ public class AbpDefaultContractResolver : DefaultContractResolver, ITransientDep if (AbpDateTimeConverter.ShouldNormalize(member, property)) { - property.Converter = _dateTimeConverter.Value; + property.Converter = _dateTimeConverter; } return property; diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs index c1f1f3a0cf..02e049ea09 100644 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.DependencyInjection; +using System; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Modularity; using Volo.Abp.Timing; @@ -10,9 +11,9 @@ public class AbpJsonNewtonsoftModule : AbpModule public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddOptions() - .Configure((options, contractResolver) => + .Configure((options, serviceProvider) => { - options.JsonSerializerSettings.ContractResolver = contractResolver; + options.JsonSerializerSettings.ContractResolver = new AbpCamelCasePropertyNamesContractResolver(serviceProvider.GetRequiredService()); }); } } diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializer.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializer.cs index 36ba95e74c..891a2210fc 100644 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializer.cs +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializer.cs @@ -34,7 +34,7 @@ public class AbpNewtonsoftJsonSerializer : IJsonSerializer, ITransientDependency return JsonConvert.DeserializeObject(jsonString, type, CreateJsonSerializerOptions(camelCase)); } - private static readonly ConcurrentDictionary JsonSerializerOptionsCache = + private readonly static ConcurrentDictionary JsonSerializerOptionsCache = new ConcurrentDictionary(); protected virtual JsonSerializerSettings CreateJsonSerializerOptions(bool camelCase = true, bool indented = false) @@ -81,9 +81,11 @@ public class AbpNewtonsoftJsonSerializer : IJsonSerializer, ITransientDependency TypeNameAssemblyFormatHandling = Options.Value.JsonSerializerSettings.TypeNameAssemblyFormatHandling }; - settings.ContractResolver = camelCase - ? ServiceProvider.GetRequiredService() - : ServiceProvider.GetRequiredService(); + if (!camelCase) + { + // Default contract resolver is AbpCamelCasePropertyNamesContractResolver} + settings.ContractResolver = new AbpDefaultContractResolver(ServiceProvider.GetRequiredService()); + } if (indented) { diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpDefaultJsonTypeInfoResolver.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpDefaultJsonTypeInfoResolver.cs index 385544dc0b..c49b37964f 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpDefaultJsonTypeInfoResolver.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpDefaultJsonTypeInfoResolver.cs @@ -1,10 +1,9 @@ using System.Text.Json.Serialization.Metadata; using Microsoft.Extensions.Options; -using Volo.Abp.DependencyInjection; namespace Volo.Abp.Json.SystemTextJson; -public class AbpDefaultJsonTypeInfoResolver : DefaultJsonTypeInfoResolver, ITransientDependency +public class AbpDefaultJsonTypeInfoResolver : DefaultJsonTypeInfoResolver { public AbpDefaultJsonTypeInfoResolver(IOptions options) { From 51424e268312c6df982595ea15d96b6fb3136408 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 17 Mar 2023 09:58:41 +0800 Subject: [PATCH 2/3] Update AbpDefaultContractResolver.cs --- .../Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs index 527a7282e6..17e180372e 100644 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpDefaultContractResolver.cs @@ -1,11 +1,10 @@ using System.Reflection; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; -using Volo.Abp.DependencyInjection; namespace Volo.Abp.Json.Newtonsoft; -public class AbpDefaultContractResolver : DefaultContractResolver, ITransientDependency +public class AbpDefaultContractResolver : DefaultContractResolver { private readonly AbpDateTimeConverter _dateTimeConverter; From dcebc141ecec31d019c79902f708350965af6860 Mon Sep 17 00:00:00 2001 From: maliming Date: Fri, 17 Mar 2023 10:07:03 +0800 Subject: [PATCH 3/3] Rename `serviceProvider` to `rootServiceProvider`. --- .../NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs | 4 ++-- .../Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs | 4 ++-- .../Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs | 4 ++-- .../Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializer.cs | 8 ++++---- .../Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs | 8 ++++---- .../Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs index 4ee0f6c831..d213c9f451 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.NewtonsoftJson/Volo/Abp/AspNetCore/Mvc/NewtonsoftJson/AbpAspNetCoreMvcNewtonsoftModule.cs @@ -14,9 +14,9 @@ public class AbpAspNetCoreMvcNewtonsoftModule : AbpModule context.Services.AddMvcCore().AddNewtonsoftJson(); context.Services.AddOptions() - .Configure((options, serviceProvider) => + .Configure((options, rootServiceProvider) => { - options.SerializerSettings.ContractResolver = new AbpCamelCasePropertyNamesContractResolver(serviceProvider.GetRequiredService()); + options.SerializerSettings.ContractResolver = new AbpCamelCasePropertyNamesContractResolver(rootServiceProvider.GetRequiredService()); }); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs index 4fc5a04859..8c6edd2eb0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Json/MvcCoreBuilderExtensions.cs @@ -13,7 +13,7 @@ public static class MvcCoreBuilderExtensions public static IMvcCoreBuilder AddAbpJson(this IMvcCoreBuilder builder) { builder.Services.AddOptions() - .Configure((options, serviceProvider) => + .Configure((options, rootServiceProvider) => { options.JsonSerializerOptions.ReadCommentHandling = JsonCommentHandling.Skip; options.JsonSerializerOptions.AllowTrailingCommas = true; @@ -24,7 +24,7 @@ public static class MvcCoreBuilderExtensions options.JsonSerializerOptions.Converters.Add(new AbpNullableStringToGuidConverter()); options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter()); - options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(serviceProvider + options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(rootServiceProvider .GetRequiredService>()); }); diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs index 02e049ea09..6f93a6c54e 100644 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpJsonNewtonsoftModule.cs @@ -11,9 +11,9 @@ public class AbpJsonNewtonsoftModule : AbpModule public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddOptions() - .Configure((options, serviceProvider) => + .Configure((options, rootServiceProvider) => { - options.JsonSerializerSettings.ContractResolver = new AbpCamelCasePropertyNamesContractResolver(serviceProvider.GetRequiredService()); + options.JsonSerializerSettings.ContractResolver = new AbpCamelCasePropertyNamesContractResolver(rootServiceProvider.GetRequiredService()); }); } } diff --git a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializer.cs b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializer.cs index 891a2210fc..4dda1f5ca5 100644 --- a/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializer.cs +++ b/framework/src/Volo.Abp.Json.Newtonsoft/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializer.cs @@ -10,12 +10,12 @@ namespace Volo.Abp.Json.Newtonsoft; [Dependency(ReplaceServices = true)] public class AbpNewtonsoftJsonSerializer : IJsonSerializer, ITransientDependency { - protected IServiceProvider ServiceProvider { get; } + protected IRootServiceProvider RootServiceProvider { get; } protected IOptions Options { get; } - public AbpNewtonsoftJsonSerializer(IServiceProvider serviceProvider, IOptions options) + public AbpNewtonsoftJsonSerializer(IRootServiceProvider rootServiceProvider, IOptions options) { - ServiceProvider = serviceProvider; + RootServiceProvider = rootServiceProvider; Options = options; } @@ -84,7 +84,7 @@ public class AbpNewtonsoftJsonSerializer : IJsonSerializer, ITransientDependency if (!camelCase) { // Default contract resolver is AbpCamelCasePropertyNamesContractResolver} - settings.ContractResolver = new AbpDefaultContractResolver(ServiceProvider.GetRequiredService()); + settings.ContractResolver = new AbpDefaultContractResolver(RootServiceProvider.GetRequiredService()); } if (indented) diff --git a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs index f6ef46a4e7..3f193398e3 100644 --- a/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs +++ b/framework/src/Volo.Abp.Json.SystemTextJson/Volo/Abp/Json/SystemTextJson/AbpJsonSystemTextJsonModule.cs @@ -15,7 +15,7 @@ public class AbpJsonSystemTextJsonModule : AbpModule public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddOptions() - .Configure((options, serviceProvider) => + .Configure((options, rootServiceProvider) => { // If the user hasn't explicitly configured the encoder, use the less strict encoder that does not encode all non-ASCII characters. options.JsonSerializerOptions.Encoder ??= JavaScriptEncoder.UnsafeRelaxedJsonEscaping; @@ -26,14 +26,14 @@ public class AbpJsonSystemTextJsonModule : AbpModule options.JsonSerializerOptions.Converters.Add(new AbpNullableStringToGuidConverter()); options.JsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter()); - options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(serviceProvider + options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(rootServiceProvider .GetRequiredService>()); }); context.Services.AddOptions() - .Configure((options, serviceProvider) => + .Configure((options, rootServiceProvider) => { - options.Modifiers.Add(new AbpDateTimeConverterModifier().CreateModifyAction(serviceProvider)); + options.Modifiers.Add(new AbpDateTimeConverterModifier().CreateModifyAction(rootServiceProvider)); }); } } diff --git a/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs b/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs index f5b6a39bf4..4435f1dcf0 100644 --- a/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs +++ b/framework/test/Volo.Abp.MemoryDb.Tests/Volo/Abp/MemoryDb/AbpMemoryDbTestModule.cs @@ -35,10 +35,10 @@ public class AbpMemoryDbTestModule : AbpModule }); context.Services.AddOptions() - .Configure((options, serviceProvider) => + .Configure((options, rootServiceProvider) => { options.JsonSerializerOptions.Converters.Add(new EntityJsonConverter()); - options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(serviceProvider + options.JsonSerializerOptions.TypeInfoResolver = new AbpDefaultJsonTypeInfoResolver(rootServiceProvider .GetRequiredService>()); }); }