Search code examples
.netvalueinjecterprodinner

convert int[] to Entities using Value Injecter


In the "ProDinner" project, ValueInjecter is used for mapping.I use the newest version, which replace ConventionInjection with LoopInjection when convert between entities and int[],I have got the code of EntitiesToInts class:

public class EntitiesToInts : LoopInjection
{
    protected override bool MatchTypes(Type src, Type trg)
    {
        return trg == typeof(int[])
            && src.IsGenericType 
            && src.GetGenericTypeDefinition() == typeof(ICollection<>)
            && src.GetGenericArguments()[0].IsSubclassOf(typeof(Entity));
    }

    protected override void SetValue(object source, object target, PropertyInfo sp, PropertyInfo tp)
    {
        var val = sp.GetValue(source);
        if (val != null)
        {
            tp.SetValue(target, (val as IEnumerable<Entity>).Select(o => o.Id).ToArray());
        }
    }
}

How to finish IntsToEntities class?


Solution

  • the IntsToEntities is there, you can see it being used in the DefaultMapper in MapperConfig class

    // go from int[] to ICollection<Entity> 
    public class IntsToEntities : LoopInjection
    {
        protected override bool MatchTypes(Type src, Type trg)
        {
            return src == typeof(int[]) 
                && trg.IsGenericType
                && trg.GetGenericTypeDefinition() == typeof(ICollection<>)
                && trg.GetGenericArguments()[0].IsSubclassOf(typeof(Entity));
        }
    
            protected override void SetValue(object source, object target, PropertyInfo sp, PropertyInfo tp)
            {
                var sourceVal = sp.GetValue(source);
                if (sourceVal != null)
                {
                    var tval = tp.GetValue(target);// make EF load the collection before modifying it; without it we get errors when saving an existing object
    
                    dynamic repo = IoC.Resolve(typeof(IRepo<>).MakeGenericType(tp.PropertyType.GetGenericArguments()[0]));
                    dynamic resList = Activator.CreateInstance(typeof(List<>).MakeGenericType(tp.PropertyType.GetGenericArguments()[0]));
    
                    var sourceAsArr = (int[])sourceVal;
                    foreach (var i in sourceAsArr)
                        resList.Add(repo.Get(i));
    
                    tp.SetValue(target, resList);
                }
            }
        }