using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; 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.ObjectConverter { public abstract class LuObjectConverterLists : ILuObjectConverter { protected IServiceProvider ServiceProvider { get; } public LuObjectConverterLists(IServiceProvider serviceProvider) { ServiceProvider = serviceProvider; } protected abstract Type GetListType(); public LuResult Convert(object srcObj, LuPartialFieldsDbo fields, ILuObjectConverterOptions options) { if (srcObj is IEnumerable enumerable) { var listType = GetListType(); var listTypeTo = options.TypeConverter.ConvertType(srcObj.GetType().GetGenericArguments()[0]); var glistType = listType.MakeGenericType(listTypeTo); var collection = options.Allocator.GetInstance(glistType); foreach (var obj in enumerable) { object convertedObj = null; if (obj != null) { var typeFrom = obj.GetType(); var typeTo = options.TypeConverter.ConvertType(typeFrom); // TODO Handle converter == null var converter = LuObjectConverterUtils.GetObjectConverter(ServiceProvider, typeFrom, typeTo); var convertResult = converter.Convert(obj, fields, options); if (!convertResult) { return convertResult; } convertedObj = convertResult.Data; } var methodInfo = collection.GetType().GetMethod(nameof(ICollection.Add)); methodInfo.Invoke(collection, new []{convertedObj}); } return LuResult.Ok(collection); } else { return LuResult.Error(LuStatus.InputError.ToInt(), $"Could not convert {nameof(srcObj)} to {nameof(IEnumerable)}"); } } } public class LuObjectConverterList : LuObjectConverterLists { public LuObjectConverterList(IServiceProvider serviceProvider) : base(serviceProvider) { } protected override Type GetListType() { return typeof(List<>); } } public class LuObjectConverterCollection : LuObjectConverterLists { public LuObjectConverterCollection(IServiceProvider serviceProvider) : base(serviceProvider) { } protected override Type GetListType() { return typeof(Collection<>); } } }