using System; using System.Collections; using System.Collections.Generic; using Luticate2.Auth.Utils.Dbo; using Luticate2.Auth.Utils.Dbo.Fields; using Luticate2.Auth.Utils.Dbo.Result; using Luticate2.Auth.Utils.Interfaces; namespace Luticate2.Auth.Utils.Business.Converters.ObjectConverter { public class LuObjectConverterLists : ILuObjectConverter { protected IServiceProvider ServiceProvider { get; } public LuObjectConverterLists(IServiceProvider serviceProvider) { ServiceProvider = serviceProvider; } public LuResult Convert(object srcObj, object dstObj, LuFieldDbo path, LuPartialFieldsDbo fields, ILuObjectConverterOptions options) { var dstObjType = dstObj.GetType(); var addMethodInfo = dstObjType.GetMethod(nameof(ICollection.Add)); if (addMethodInfo == null) { return LuResult.Error(LuStatus.InternalError.ToInt(), $"Could not find get method info {nameof(ICollection)}.{nameof(ICollection.Add)} for type {dstObjType}"); } if (srcObj is IEnumerable enumerable) { foreach (var subSrcObj in enumerable) { object convertedObj = null; if (subSrcObj != null) { var typeFrom = subSrcObj.GetType(); var typeToResult = options.TypeConverter.ConvertType(typeFrom); if (!typeToResult) { return typeToResult.To(); } var typeTo = typeToResult.Data; var converterResult = LuObjectConverterUtils.GetObjectConverter(ServiceProvider, typeFrom, typeTo); if (!converterResult) { return converterResult.To(); } var converter = converterResult.Data; var subDstObjResult = options.Allocator.GetInstance(typeTo); if (!subDstObjResult) { return subDstObjResult.To(); } var subDstObj = subDstObjResult.Data; var convertResult = converter.Convert(subSrcObj, subDstObj, path, fields, options); if (!convertResult) { return convertResult; } convertedObj = convertResult.Data; } addMethodInfo.Invoke(dstObj, new []{convertedObj}); } return LuResult.Ok(dstObj); } else { return LuResult.Error(LuStatus.InputError.ToInt(), $"Could not convert {nameof(srcObj)} to {nameof(IEnumerable)}"); } } } }