mardi 22 juin 2021

Using the recursive function by making the type transformation in the generic method at run time

I have a list from AppLayerGroup class, within this list I have another list from AppLayer class. What I want to do is to translate each property of the list I send to the TranslateList method into a language of my choice. If the corresponding value of each property of the list exists in the view, I update it. If the property is a list, I try to send the new list back to the Translate method with the help of the recursive function. But type 'T' is not same as first time type, I need to convert it at runtime but I don't know how to do that.

    public class AppLayer : IEntity
    {
        public int Id { get; set; }
        public int AppLayerGroupId { get; set; }
        public string LayerName { get; set; }
    }

    public class AppLayerGroup : IEntity
    {
        public int Id { get; set; }
        public string GroupKey { get; set; }
        public virtual ICollection<AppLayer> AppLayer { get; set; }
    }
    public static IEnumerable<T> TranslateList<T>(this IEnumerable<T> data)
    {
        var _httpContextAccessor = (IHttpContextAccessor)ServiceTool.ServiceProvider.GetService(typeof(IHttpContextAccessor));
        var userId = _httpContextAccessor.HttpContext?.User.Claims.FirstOrDefault(x => x.Type.EndsWith("nameidentifier"))?.Value;
        var _cacheManager = (ICacheManager)ServiceTool.ServiceProvider.GetService(typeof(ICacheManager));

        short appLangId = Convert.ToInt16(_cacheManager.Get($"{CacheKeys.UserLang}={userId}"));

        Translate(data, appLangId);

        return data;
    }

    

    public static IEnumerable<T> Translate<T>(IEnumerable<T> data, short appLangId)
    {
        string classname = (data.FirstOrDefault() as Castle.DynamicProxy.IProxyTargetAccessor).DynProxyGetTarget().GetType().BaseType.Name;

        var _vAppLookupLanguageRepository = (IVAppLookupLanguageRepository)ServiceTool.ServiceProvider.GetService(typeof(IVAppLookupLanguageRepository));
        var langList = _vAppLookupLanguageRepository.GetList(a => a.EntityName == classname && a.AppLanguageId == appLangId);

        if (langList.IsAny() && data.IsAny())
        {
            foreach (var item in data )
            {
                foreach (PropertyInfo prop in item.GetType().GetProperties())
                {
                    if (prop.PropertyType.GetInterface("IEnumerable").Name == "IEnumerable")
                    {
                        var subList = (IEnumerable)prop.GetValue(item, null);

                        Translate((IEnumerable<T>)subList, 2); //I should submit the type of subList instead of 'T'
                    }
                    if (langList.Any(a => a.ColumnName == prop.Name))
                        prop.SetValue(item, langList.FirstOrDefault(a => a.UniqueValue == prop.GetValue(item).ToString()).LanguageValue, null);
                }
            }
        }

        return data;
    }

I did some research but couldn't find the right result.





Aucun commentaire:

Enregistrer un commentaire