diff --git a/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpListExtensions.cs b/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpListExtensions.cs index ec7a640a39..ac71649793 100644 --- a/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpListExtensions.cs +++ b/framework/src/Volo.Abp.Core/System/Collections/Generic/AbpListExtensions.cs @@ -9,6 +9,14 @@ namespace System.Collections.Generic /// public static class AbpListExtensions { + public static void InsertRange(this IList source, int index, IEnumerable items) + { + foreach (var item in items) + { + source.Insert(index++, item); + } + } + public static int FindIndex(this IList source, Predicate selector) { for (var i = 0; i < source.Count; ++i) @@ -182,7 +190,7 @@ namespace System.Collections.Generic /// Function to resolve the dependencies /// /// Returns a new list ordered by dependencies. - /// If A depends on B, then B will come before than A in the resulting list. + /// If A depends on B, then B will come before than A in the resulting list. /// public static List SortByDependencies(this IEnumerable source, Func> getDependencies) { @@ -202,14 +210,15 @@ namespace System.Collections.Generic } /// - /// + /// /// /// The type of the members of values. /// Item to resolve /// Function to resolve the dependencies /// List with the sortet items /// Dictionary with the visited items - private static void SortByDependenciesVisit(T item, Func> getDependencies, List sorted, Dictionary visited) + private static void SortByDependenciesVisit(T item, Func> getDependencies, List sorted, + Dictionary visited) { bool inProcess; var alreadyVisited = visited.TryGetValue(item, out inProcess); diff --git a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs index 533b76aa6c..af9eb59b7f 100644 --- a/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs +++ b/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs @@ -17,7 +17,6 @@ using Volo.Abp.Http.Modeling; using Volo.Abp.Http.ProxyScripting.Generators; using Volo.Abp.Json; using Volo.Abp.MultiTenancy; -using Volo.Abp.Reflection; using Volo.Abp.Threading; using Volo.Abp.Tracing; diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs index dcb8f28dff..c3ea13da43 100644 --- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs +++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/AbpJsonModule.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Modularity; +using Volo.Abp.Json.Newtonsoft; +using Volo.Abp.Modularity; using Volo.Abp.Timing; namespace Volo.Abp.Json @@ -6,6 +7,12 @@ namespace Volo.Abp.Json [DependsOn(typeof(AbpTimingModule))] public class AbpJsonModule : AbpModule { - + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Converters.Add(); + }); + } } } diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs new file mode 100644 index 0000000000..cb1c3d9f65 --- /dev/null +++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/AbpNewtonsoftJsonSerializerOptions.cs @@ -0,0 +1,15 @@ +using Newtonsoft.Json; +using Volo.Abp.Collections; + +namespace Volo.Abp.Json.Newtonsoft +{ + public class AbpNewtonsoftJsonSerializerOptions + { + public ITypeList Converters { get; } + + public AbpNewtonsoftJsonSerializerOptions() + { + Converters = new TypeList(); + } + } +} diff --git a/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/NewtonsoftJsonSerializer.cs b/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/NewtonsoftJsonSerializer.cs index 99252b8448..20e49ac817 100644 --- a/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/NewtonsoftJsonSerializer.cs +++ b/framework/src/Volo.Abp.Json/Volo/Abp/Json/Newtonsoft/NewtonsoftJsonSerializer.cs @@ -1,4 +1,8 @@ using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using Volo.Abp.DependencyInjection; @@ -7,14 +11,19 @@ namespace Volo.Abp.Json.Newtonsoft { public class NewtonsoftJsonSerializer : IJsonSerializer, ITransientDependency { - private readonly AbpJsonIsoDateTimeConverter _dateTimeConverter; - private static readonly CamelCaseExceptDictionaryKeysResolver SharedCamelCaseExceptDictionaryKeysResolver = new CamelCaseExceptDictionaryKeysResolver(); - public NewtonsoftJsonSerializer(AbpJsonIsoDateTimeConverter dateTimeConverter) + protected List Converters { get; } + + public NewtonsoftJsonSerializer( + IOptions options, + IServiceProvider serviceProvider) { - _dateTimeConverter = dateTimeConverter; + Converters = options.Value + .Converters + .Select(c => (JsonConverter) serviceProvider.GetRequiredService(c)) + .ToList(); } public string Serialize(object obj, bool camelCase = true, bool indented = false) @@ -36,8 +45,8 @@ namespace Volo.Abp.Json.Newtonsoft { var settings = new JsonSerializerSettings(); - settings.Converters.Insert(0, _dateTimeConverter); - + settings.Converters.InsertRange(0, Converters); + if (camelCase) { settings.ContractResolver = SharedCamelCaseExceptDictionaryKeysResolver; @@ -47,7 +56,7 @@ namespace Volo.Abp.Json.Newtonsoft { settings.Formatting = Formatting.Indented; } - + return settings; } @@ -63,4 +72,4 @@ namespace Volo.Abp.Json.Newtonsoft } } } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PeopleAppService_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PeopleAppService_Tests.cs index 96a79d8971..aae7345908 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PeopleAppService_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PeopleAppService_Tests.cs @@ -83,7 +83,6 @@ namespace Volo.Abp.AspNetCore.Mvc (await _personRepository.FindAsync(resultDto.Id)).ShouldNotBeNull(); } - [Fact] public async Task Update_Test() { @@ -170,4 +169,4 @@ namespace Volo.Abp.AspNetCore.Mvc douglas.Phones.Any(p => p.Number == firstPhone.Number).ShouldBeFalse(); } } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.Core.Tests/System/Collections/Generic/AbpListExtensions_Tests.cs b/framework/test/Volo.Abp.Core.Tests/System/Collections/Generic/AbpListExtensions_Tests.cs index 9c8926f38a..618b8769dc 100644 --- a/framework/test/Volo.Abp.Core.Tests/System/Collections/Generic/AbpListExtensions_Tests.cs +++ b/framework/test/Volo.Abp.Core.Tests/System/Collections/Generic/AbpListExtensions_Tests.cs @@ -7,6 +7,20 @@ namespace System.Collections.Generic { public class AbpListExtensions_Tests { + [Fact] + public void InsertRange() + { + var list = Enumerable.Range(1, 3).ToList(); + list.InsertRange(1, new[] {7, 8, 9}); + + list[0].ShouldBe(1); + list[1].ShouldBe(7); + list[2].ShouldBe(8); + list[3].ShouldBe(9); + list[4].ShouldBe(2); + list[5].ShouldBe(3); + } + [Fact] public void InsertAfter() { @@ -191,7 +205,7 @@ namespace System.Collections.Generic { var list = RandomHelper .GenerateRandomizedList(new char[] {'A', 'B', 'C', 'D', 'E', 'F', 'G'}); - + list = list.SortByDependencies(c => dependencies[c]); foreach (var dependency in dependencies) @@ -204,4 +218,4 @@ namespace System.Collections.Generic } } } -} \ No newline at end of file +}