using System; using Luticate2.Auth.Utils.Business.ExpressionConverter; using Luticate2.Auth.Utils.Business.Utils; using Luticate2.Auth.Utils.Dbo.Fields; using Luticate2.Auth.Utils.Dbo.Result; using Luticate2.Auth.Utils.Interfaces; using Microsoft.Extensions.DependencyInjection; namespace Luticate2.Auth.Utils.Business.ObjectConverter { public class LuObjectConverterPoco : ILuObjectConverter { protected IServiceProvider ServiceProvider { get; } public LuObjectConverterPoco(IServiceProvider serviceProvider) { ServiceProvider = serviceProvider; } protected ILuObjectConverter GetObjectConverter(Type typeFrom, Type typeTo) { var type = typeof(ILuObjectConverter<,>); var gtype = type.MakeGenericType(typeFrom, typeTo); var converter = (ILuObjectConverter) ServiceProvider.GetService(gtype); if (converter == null && typeFrom == typeTo) { converter = (ILuObjectConverter) ServiceProvider.GetService(typeof(ILuObjectConverterIdentity)); } return converter; } public LuResult Convert(object srcObj, LuPartialFieldsDbo fields, LuExpressionConverterOptions options) { // TODO Check if this is correct if (srcObj == null) { return LuResult.Ok(default(TTypeTo)); } // TODO Handle descriptor == null var descriptor = ServiceProvider.GetService>(); var typeTo = typeof(TTypeTo); var dstObj = options.Allocator(typeTo); foreach (var memberInfo in typeTo.GetProperties()) { // TODO check if field is included in fields // TODO Handle valueExpression == null var srcPropExpression = descriptor.GetMemberValueExpression(memberInfo, options); var srcPropDelegate = srcPropExpression.Compile(); var srcProp = srcPropDelegate.DynamicInvoke(srcObj); var objectConverter = GetObjectConverter(srcProp.GetType(), memberInfo.GetUnderlyingType()); var dstProp = objectConverter.Convert(srcProp, fields, options); if (!dstProp) { return dstProp; } var result = LuExpressionUtils.SetValueFromMember(memberInfo, dstObj, dstProp.Data); if (!result) { return result.To(); } } return LuResult.Ok(dstObj); } } }