Exemplo n.º 1
0
        private void GetDummyDictionary(
            IEnumerable <dynamic> dResult,
            string memberName,
            bool nested,
            bool isAnInterface,
            bool cleanResult,
            Type dictType,
            Type masterType)
        {
            string[] keyValueNames = _Dictionaries[masterType][memberName];
            Type     keysType      = dictType.GenericTypeArguments[0]; //keys types of dummy dict
            Type     valuesType    = dictType.GenericTypeArguments[1]; //values types of dummy dict

            this.DummyDictionary = (IDictionary)Activator.CreateInstance(typeof(Dictionary <,>).MakeGenericType(dictType.GenericTypeArguments));

            if (!nested)
            {
                bool noKeys = true;
                foreach (dynamic dyn in dResult)
                {
                    IDictionary <string, object> dict = dyn as IDictionary <string, object>;
                    if (!dict.ContainsKey(keyValueNames[0]))
                    {
                        continue;
                    }
                    if (this.DummyDictionary.Contains(dict[keyValueNames[0]]))
                    {
                        continue;
                    }

                    noKeys = false;
                    if (!dict.ContainsKey(keyValueNames[1]))
                    {
                        DummyDictionary.Add(dict[keyValueNames[0]], GetDefault(valuesType));
                    }
                    else
                    {
                        DummyDictionary.Add(dict[keyValueNames[0]], dict[keyValueNames[1]]);
                    }
                }
                //if there aren't any key correct, exception
                if (noKeys)//preDummy == null)//(!preDummy.Any(dyn => dyn.ContainsKey(keyValueNames[0])))
                {
                    throw new CustomException_DapperMapper(
                              $@"DictionaryMapper.GetDummyDictionary: Dynamic dapper result doesn't have members with the name 
required to create dictionary {memberName} keys in {masterType.Name}. Key-value names configurated: ({keyValueNames[0]}, {keyValueNames[1]})");
                }
            }
            else
            {
                MapperStore store = new MapperStore();

                if (isAnInterface)
                {
                    bool keysAreInterface =
                        keysType.IsInterface &&
                        !typeof(IDictionary).IsAssignableFrom(keysType) &&
                        !(typeof(IEnumerable).IsAssignableFrom(keysType) && !typeof(string).IsAssignableFrom(keysType));
                    bool valuesAreInterface =
                        valuesType.IsInterface &&
                        !typeof(IDictionary).IsAssignableFrom(valuesType) &&
                        !(typeof(IEnumerable).IsAssignableFrom(valuesType) && !typeof(string).IsAssignableFrom(valuesType));

                    if (keysAreInterface)
                    {
                        keysType = ResolveInterface(keysType, dResult);
                    }
                    if (valuesAreInterface)
                    {
                        valuesType = ResolveInterface(valuesType, dResult);
                    }
                }
                iDapperMapper keysNestedMapper   = store.GetMapper(keysType);
                iDapperMapper valuesNestedMapper = store.GetMapper(valuesType);

                //if there aren't any key correct, exception
                if (keysNestedMapper != null && !keysNestedMapper.CheckIfDynamicHasAllTypeMembersByName(dResult.First()))
                {
                    throw new CustomException_DapperMapper(
                              $@"DictionaryMapper.GetDummyDictionary: Dynamic dapper result doesn't have members with the name 
required to create dictionary {memberName} in {masterType.Name}. Key-value names configurated: ({keyValueNames[0]}, {keyValueNames[1]})");
                }

                //if both keys and values are nested types
                if (keysNestedMapper != null && valuesNestedMapper != null)
                {
                    foreach (dynamic dyn in dResult)
                    {
                        dynamic cleanDyn = GetCleanResult(dyn, keysNestedMapper, valuesNestedMapper, cleanResult);
                        object  key      = keysNestedMapper.NoGenericMap(cleanDyn, true);

                        if (this.DummyDictionary.Contains(key))
                        {
                            continue;
                        }

                        this.DummyDictionary.Add(
                            key,
                            valuesNestedMapper.NoGenericMap(cleanDyn, true));
                    }
                }
                //if only values are nested
                else if (keysNestedMapper == null)
                {
                    foreach (dynamic dyn in dResult)
                    {
                        IDictionary <string, object> dict = (IDictionary <string, object>)dyn;
                        if (!dict.ContainsKey(keyValueNames[0]))
                        {
                            continue;
                        }

                        dynamic cleanDyn = GetCleanResult(dyn, keyValueNames[0], valuesNestedMapper, cleanResult);
                        dict = (IDictionary <string, object>)cleanDyn;

                        if (this.DummyDictionary.Contains(dict[keyValueNames[0]]))
                        {
                            continue;
                        }

                        if (!dict.ContainsKey(keyValueNames[1]))
                        {
                            this.DummyDictionary.Add(dict[keyValueNames[0]], GetDefault(valuesType));
                        }
                        else
                        {
                            this.DummyDictionary.Add(dict[keyValueNames[0]], valuesNestedMapper.NoGenericMap(cleanDyn, true));
                        }
                    }
                }
                //if only keys are nested
                else
                {
                    //bool noKeys = true;
                    foreach (dynamic dyn in dResult)
                    {
                        IDictionary <string, object> dict = (IDictionary <string, object>)dyn;
                        //if (!keysNestedMapper.CheckIfDynamicHasAllTypeMembersByName(dyn)) continue;

                        //noKeys = false;
                        dynamic cleanDyn = GetCleanResult(dyn, keysNestedMapper, keyValueNames[1], cleanResult);
                        dict = (IDictionary <string, object>)cleanDyn;

                        object key = keysNestedMapper.NoGenericMap(cleanDyn, true);
                        if (this.DummyDictionary.Contains(key))
                        {
                            continue;
                        }

                        if (!dict.ContainsKey(keyValueNames[1]))
                        {
                            this.DummyDictionary.Add(key, GetDefault(valuesType));
                        }
                        else
                        {
                            this.DummyDictionary.Add(key, dict[keyValueNames[1]]);
                        }
                    }
                    //if there aren't any key correct, exception
//                    if (noKeys)//preDummy == null)
//                        throw new CustomException_DapperMapper(
//                            $@"DictionaryMapper.GetDummyDictionary: Dynamic dapper result doesn't have members with the name
//required to create dictionary {memberName} in {masterType.Name}. Key-value names configurated: ({keyValueNames[0]}, {keyValueNames[1]})");
                }
            }
        }
Exemplo n.º 2
0
        private void GetDummyEnumerable(IEnumerable <dynamic> cleanDapperResult, string memberName, bool nested, bool allowDuplicates, Type enumType, Type TType)
        {
            if (!nested)
            {
                if (!allowDuplicates)
                {
                    this.DummyEnumerable = cleanDapperResult
                                           .Select(dyn => (IDictionary <string, object>)dyn)
                                           .Select(dict => dict[memberName])
                                           .Distinct();
                }
                else
                {
                    this.DummyEnumerable = cleanDapperResult
                                           .Select(dyn => (IDictionary <string, object>)dyn)
                                           .Select(dict => dict[memberName]);
                }
            }
            else
            {
                Type genericType        = enumType.GenericTypeArguments[0];
                bool genericIsInterface =
                    genericType.IsInterface &&
                    !typeof(IDictionary).IsAssignableFrom(genericType) &&
                    !(typeof(IEnumerable).IsAssignableFrom(genericType) && !typeof(string).IsAssignableFrom(genericType));
                if (genericIsInterface)
                {
                    genericType = ResolveInterface(genericType, cleanDapperResult);
                }
                MapperStore   store        = new MapperStore();
                iDapperMapper nestedMapper = store.GetMapper(genericType);

                if (typeof(IList).IsAssignableFrom(enumType))
                {
                    IList result = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(genericType));
                    if (!allowDuplicates)
                    {
                        IEnumerable <dynamic> distinctCleanResult = nestedMapper.GetDistinctDapperResult(cleanDapperResult, true);
                        foreach (dynamic dyn in distinctCleanResult)
                        {
                            result.Add(nestedMapper.NoGenericMap(dyn, true));
                        }
                    }
                    else
                    {
                        foreach (dynamic dyn in cleanDapperResult)
                        {
                            result.Add(nestedMapper.NoGenericMap(dyn, true));
                        }
                    }
                    this.DummyEnumerable = result;
                }
                else
                {
                    //http://stackoverflow.com/questions/18251587/assign-any-ienumerable-to-object-property
                    var addMethod = enumType.GetMethod("Add", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);

                    // Property doesn't support Adding
                    if (addMethod == null) //throw new InvalidOperationException("Method Add does not exist on class " + enumType.Name);
                    {
                        throw new CustomException_DapperMapper(
                                  $@"EnumerableMapper.GetDummyEnumerable: Method Add doesn't exist in enumerable type to map.
enumType: {enumType.Name} ; member name: {memberName}.");
                    }

                    if (enumType.IsGenericTypeDefinition)
                    {
                        this.DummyEnumerable = (IEnumerable)Activator.CreateInstance(enumType.MakeGenericType(genericType));
                    }
                    else
                    {
                        this.DummyEnumerable = (IEnumerable)Activator.CreateInstance(enumType);
                    }

                    if (!allowDuplicates)
                    {
                        IEnumerable <dynamic> distinctCleanResult = nestedMapper.GetDistinctDapperResult(cleanDapperResult, true);
                        foreach (dynamic dyn in distinctCleanResult)
                        {
                            addMethod.Invoke(this.DummyEnumerable, new object[] { nestedMapper.NoGenericMap(dyn, true) });
                        }
                    }
                    else
                    {
                        foreach (dynamic dyn in cleanDapperResult)
                        {
                            addMethod.Invoke(this.DummyEnumerable, new object[] { nestedMapper.NoGenericMap(dyn, true) });
                        }
                    }
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Generic Map.
        /// </summary>
        /// <param name="dapperResult"></param>
        /// <returns></returns>
        public T Map(IEnumerable <dynamic> dapperResult, bool cleanResult = false)
        {
            var parser = new PrePostFixesParser(this);
            T   mapped = this.NewObject(dapperResult.First());

            if (_OnlyConstructor.Contains(this.TType))
            {
                return(mapped);
            }

            //TODO: divide el siguiente foreach en dos con dos nuevos diccionarios estáticos, uno para pInfos y otro para fInfos,
            //aunque se repita código: hacer métodos para cada parte del código del tipo:
            //private T PreMapCreator(KeyValuePair<PropertyInfo, MemberTypeInfo> kvp, IEnumerable<dynamic> dapperResult, bool cleanResult = false)
            //private T PreMapIEnumerable(KeyValuePair<PropertyInfo, MemberTypeInfo> kvp, IEnumerable<dynamic> dapperResult, bool cleanResult = false)
            //...

            //Loop through all members
            foreach (KeyValuePair <MemberInfo, MemberTypeInfo> kvp in mtInfos)
            {
                if (kvp.Value == MemberTypeInfo.Ignore)
                {
                    continue;
                }
                //Member have a creator
                else if ((kvp.Value & MemberTypeInfo.Creator) == MemberTypeInfo.Creator)
                {
                    //MemberDelegate mDel = (MemberDelegate)_MembersCreators[this.TType][kvp.Key.Name];
                    Func <dynamic, object> mDel = (Func <dynamic, object>)_MembersCreators[this.TType][kvp.Key.Name];

                    if (kvp.Key.MemberType == MemberTypes.Property)
                    {
                        ((PropertyInfo)kvp.Key).SetValue(mapped, mDel(dapperResult));
                    }
                    else
                    {
                        ((FieldInfo)kvp.Key).SetValue(mapped, mDel(dapperResult));
                    }
                }
                //Member is IDictionary or IEnumerable
                else if ((kvp.Value & MemberTypeInfo.IEnumerable) == MemberTypeInfo.IEnumerable)
                {
                    Type t = GetMemberType(kvp.Key);
                    //if ((kvp.Value & MemberTypeInfo.Interface) == MemberTypeInfo.Interface) t = ResolveInterface(kvp.Key, dapperResult);
                    //else t = GetMemberType(kvp.Key);

                    /*
                     * {
                     *  //Type of property or field
                     *  if (kvp.Key.MemberType == MemberTypes.Property) t = ((PropertyInfo)kvp.Key).PropertyType;
                     *  else t = ((FieldInfo)kvp.Key).FieldType;
                     * }*/
                    bool isAnInterface = (kvp.Value & MemberTypeInfo.Interface) == MemberTypeInfo.Interface;
                    bool isNested      = (kvp.Value & MemberTypeInfo.Nested) == MemberTypeInfo.Nested;

                    //If member is a dictionary
                    if (typeof(IDictionary).IsAssignableFrom(t))
                    {
                        //Create a dummy dictionary with the dapper's dynamic result which should be equal to the final one
                        DictionaryMapper dictMapper = new DictionaryMapper(dapperResult, kvp.Key.Name, isNested, isAnInterface, cleanResult, t, this);

                        try
                        {
                            if (kvp.Key.MemberType == MemberTypes.Property)
                            {
                                ((PropertyInfo)kvp.Key).SetValue(mapped, dictMapper.DummyDictionary);
                            }
                            else
                            {
                                ((FieldInfo)kvp.Key).SetValue(mapped, dictMapper.DummyDictionary);
                            }
                        }
                        catch (Exception err)
                        {
                            throw new CustomException_DapperMapper(
                                      $@"DapperMapper.Map: Couldn't map IDictionary member {kvp.Key.Name} with value contained by dynamic object.
Incorrect type of value?: {kvp.Value.ToString()}",
                                      err);
                        }
                    }
                    //Rest of enumerables
                    else
                    {
                        IEnumerable <dynamic> iEnumDapperResult;
                        //Select current member's values from dynamic
                        if (isNested && !cleanResult)
                        {
                            //Type mType = t; // GetMemberType(kvp.Key);//IEnumerable<T>
                            Type genericType = t.GenericTypeArguments[0];//mType.GenericTypeArguments[0];//T
                            if ((kvp.Value & MemberTypeInfo.Interface) == MemberTypeInfo.Interface)
                            {
                                bool genericIsInterfaceNotIEnumerable =
                                    genericType.IsInterface &&
                                    !typeof(IDictionary).IsAssignableFrom(genericType) &&
                                    !(typeof(IEnumerable).IsAssignableFrom(genericType) && !typeof(string).IsAssignableFrom(genericType));

                                if (genericIsInterfaceNotIEnumerable)
                                {
                                    genericType = ResolveInterface(genericType, dapperResult);
                                }
                            }

                            iDapperMapper nestedMapper = MappersStore.GetMapper(genericType);
                            var           nestedParser = new PrePostFixesParser(nestedMapper);

                            iEnumDapperResult = dapperResult
                                                .Select(dyn => nestedParser.GetTypeMembersWithoutPrePostFixes(dyn, nestedMapper.NamesList));
                        }
                        else if (!cleanResult)
                        {
                            iEnumDapperResult = dapperResult.Select(dyn => parser.RemovePrePostFixesFromDictionary(dyn));
                        }
                        else
                        {
                            iEnumDapperResult = dapperResult;
                        }

                        //Create dummy IEnumerable
                        EnumerableMapper enumMapper = new EnumerableMapper(iEnumDapperResult, kvp.Key.Name, isNested, t, this.TType);;
                        var dummy = Activator.CreateInstance(t, enumMapper.DummyEnumerable);

                        try
                        {
                            if (kvp.Key.MemberType == MemberTypes.Property)
                            {
                                ((PropertyInfo)kvp.Key).SetValue(mapped, dummy);
                            }
                            else
                            {
                                ((FieldInfo)kvp.Key).SetValue(mapped, dummy);
                            }
                        }
                        catch (Exception err)
                        {
                            throw new CustomException_DapperMapper(
                                      $@"DapperMapper.Map: Couldn't map IEnumerable member {kvp.Key.Name} with value contained by dynamic object.
Incorrect type of value?: {kvp.Value.ToString()}",
                                      err);
                        }
                    }
                }//End IDictionary/IEnumerable
                //If Built-in
                else if ((kvp.Value & MemberTypeInfo.BuiltIn) == MemberTypeInfo.BuiltIn)
                {
                    string name = parser.RemoveFieldsUnderscore(kvp.Key.Name);
                    IDictionary <string, object> dapperDict;
                    if (!cleanResult)
                    {
                        dapperDict = parser.GetTypeMembersWithoutPrePostFixes(dapperResult.First(), NamesList) as IDictionary <string, object>;
                    }
                    else
                    {
                        dapperDict = dapperResult.First() as IDictionary <string, object>;
                    }

                    if (!dapperDict.ContainsKey(name))
                    {
                        throw new CustomException_DapperMapper(
                                  $@"DapperMapper.Map: There's no member in dynamic dapper result with name {kvp.Key.Name}. Cannot Map object.");
                    }

                    try
                    {
                        if (kvp.Key.MemberType == MemberTypes.Property)
                        {
                            ((PropertyInfo)kvp.Key).SetValue(mapped, dapperDict[name]);
                        }
                        else
                        {
                            ((FieldInfo)kvp.Key).SetValue(mapped, dapperDict[name]);
                        }
                    }
                    catch (Exception err)
                    {
                        throw new CustomException_DapperMapper(
                                  $@"DapperMapper.Map: Couldn't map BuiltIn-type member {kvp.Key.Name} with value contained by dynamic object.
Incorrect type of value?: {kvp.Value.ToString()}",
                                  err);
                    }
                }
                //if nested
                else if ((kvp.Value & MemberTypeInfo.Nested) == MemberTypeInfo.Nested)
                {
                    Type mType = GetMemberType(kvp.Key);

                    if ((kvp.Value & MemberTypeInfo.Interface) == MemberTypeInfo.Interface)
                    {
                        mType = ResolveInterface(mType, dapperResult);
                    }

                    //access generic Map method through nongeneric interface method
                    iDapperMapper nestedMapper = MappersStore.GetMapper(mType);

                    if (nestedMapper == null)
                    {
                        throw new CustomException_DapperMapper(
                                  $@"DapperMapper.Map: No Mapper found at store for property {kvp.Key.Name} of type {mType.ToString()}.
If you want to map a nested property you have to create a mapper for that property type.");
                    }

                    if (kvp.Key.MemberType == MemberTypes.Property)
                    {
                        ((PropertyInfo)kvp.Key).SetValue(mapped, nestedMapper.NoGenericMap(dapperResult, cleanResult));
                    }
                    else
                    {
                        ((FieldInfo)kvp.Key).SetValue(mapped, nestedMapper.NoGenericMap(dapperResult, cleanResult));
                    }
                }
            }

            return(mapped);
        }