public Func <TSrc, TDest> GetConverter <TSrc, TDest>()
            {
                // Give precedence to exact matches.
                // this lets callers override any other rules (like JSON binding)

                // TSrc --> TDest
                Func <TSrc, TDest> exactMatch = TryGetConverter <TSrc, TDest>();

                if (exactMatch != null)
                {
                    return(exactMatch);
                }

                // string --> TDest
                Func <string, TDest> fromString = TryGetConverter <string, TDest>();

                if (fromString == null)
                {
                    string msg = string.Format(CultureInfo.CurrentCulture, "Can't convert from {0} to {1}", "string", typeof(TDest).FullName);
                    throw new NotImplementedException(msg);
                }

                // String --> TDest
                if (typeof(TSrc) == typeof(string))
                {
                    return(src =>
                    {
                        var result = fromString((string)(object)src);
                        return result;
                    });
                }

                // Allow some well-defined intermediate conversions.
                // If this is "wrong" for your type, then it should provide an exact match to override.

                // Byte[] --[builtin]--> String --> TDest
                if (typeof(TSrc) == typeof(byte[]))
                {
                    Func <byte[], string> bytes2string = TryGetConverter <byte[], string>();

                    return(src =>
                    {
                        byte[] bytes = (byte[])(object)src;
                        string str = bytes2string(bytes);
                        var result = fromString(str);
                        return result;
                    });
                }

                // TSrc --[Json]--> string --> TDest
                return((src) =>
                {
                    string json = JsonConvert.SerializeObject(src);
                    TDest obj = fromString(json);
                    return obj;
                });
            }
Пример #2
0
            /// <summary>
            /// 替换转换单元
            /// </summary>
            /// <typeparam name="TSource">要被替换掉的转换单元</typeparam>
            /// <typeparam name="TDest">替换后的转换单元</typeparam>
            /// <returns></returns>
            public ContertItems Repace <TSource, TDest>()
                where TSource : IConvert
                where TDest : IConvert
            {
                LinkedListNode <IConvert> node = this.FindNode <TSource>();

                if (node != null && this.ExistConvert <TDest>() == false)
                {
                    TDest convert = Activator.CreateInstance <TDest>();
                    node.Value = convert;
                }
                return(this.ReInitItems());
            }
Пример #3
0
            /// <summary>
            /// 添加到指定转换单元之后
            /// </summary>
            /// <typeparam name="TSource">已存在的转换单元</typeparam>
            /// <typeparam name="TDest">新加入的转换单元</typeparam>
            /// <returns></returns>
            public ContertItems AddBefore <TSource, TDest>()
                where TSource : IConvert
                where TDest : IConvert
            {
                LinkedListNode <IConvert> node = this.FindNode <TSource>();

                if (node != null && this.ExistConvert <TDest>() == false)
                {
                    TDest convert = Activator.CreateInstance <TDest>();
                    this.linkedList.AddBefore(node, convert);
                }
                return(this.ReInitItems());
            }
        private Func <TSource, TDest> GetMappingDelegate <TSource, TDest>()
            where TDest : new()
        {
            Action <TSource, TDest> mapAction = null;

            return(source =>
            {
                var dest = new TDest();
                if (mapAction == null)
                {
                    mapAction = GetMapper(source, dest);
                }
                mapAction(source, dest);

                return dest;
            });
        }
Пример #5
0
        public FuncConverter <TSrc, TAttribute, TDest> GetConverter <TSrc, TDest, TAttribute>()
            where TAttribute : Attribute
        {
            // Give precedence to exact matches.
            // this lets callers override any other rules (like JSON binding)

            // TSrc --> TDest
            var exactMatch = TryGetConverter <TSrc, TAttribute, TDest>();

            if (exactMatch != null)
            {
                return(exactMatch);
            }

            var typeSource = typeof(TSrc);
            var typeDest   = typeof(TDest);

            // Inheritence (also covers idempotency)
            if (typeDest.IsAssignableFrom(typeSource))
            {
                // Skip implicit conversions to object since that's everybody's base
                // class and BindToInput<attr,Object> would catch everything.
                // Users can still register an explicit T-->object converter if they want to
                // support it.
                if (typeDest != typeof(Object))
                {
                    return((src, attr, context) =>
                    {
                        object obj = (object)src;
                        return (TDest)obj;
                    });
                }
            }

            // Object --> TDest
            // Catch all for any conversion to TDest
            var objConversion = TryGetConverter <object, TAttribute, TDest>();

            if (objConversion != null)
            {
                return((src, attr, context) =>
                {
                    var result = objConversion(src, attr, context);
                    return result;
                });
            }

            {
                var builder = TryGetOpenConverter(typeSource, typeDest, typeof(TAttribute));
                if (builder != null)
                {
                    var converter = builder(typeSource, typeDest);
                    return((src, attr, context) => (TDest)converter(src));
                }
            }

            // TSrc --> IEnum<JObject> --> JArray
            if (typeDest == typeof(JArray))
            {
                var toEnumerableJObj = TryGetConverter <TSrc, TAttribute, IEnumerable <JObject> >();
                if (toEnumerableJObj != null)
                {
                    var toJArray = TryGetConverter <IEnumerable <JObject>, TAttribute, JArray>();
                    if (toJArray != null)
                    {
                        return((src, attr, context) =>
                        {
                            var ieJo = toEnumerableJObj(src, attr, context);
                            var result = toJArray(ieJo, attr, context);
                            return (TDest)(object)result;
                        });
                    }
                }
            }

            // string --> TDest
            var fromString = TryGetConverter <string, TAttribute, TDest>();

            if (fromString == null)
            {
                return(null);
            }

            // String --> TDest
            if (typeSource == typeof(string))
            {
                return((src, attr, context) =>
                {
                    var result = fromString((string)(object)src, attr, context);
                    return result;
                });
            }

            // Allow some well-defined intermediate conversions.
            // If this is "wrong" for your type, then it should provide an exact match to override.

            // Byte[] --[builtin]--> String --> TDest
            if (typeSource == typeof(byte[]))
            {
                var bytes2string = TryGetConverter <byte[], TAttribute, string>();

                return((src, attr, context) =>
                {
                    byte[] bytes = (byte[])(object)src;
                    string str = bytes2string(bytes, attr, context);
                    var result = fromString(str, attr, context);
                    return result;
                });
            }

            // General JSON serialization rule.

            if (typeSource.IsPrimitive ||
                (typeSource == typeof(object)) ||
                typeof(IEnumerable).IsAssignableFrom(typeSource))
            {
                return(null);
            }

            var funcJobj = TryGetConverter <object, TAttribute, JObject>();

            if (funcJobj == null)
            {
                funcJobj = (object obj, TAttribute attr, ValueBindingContext context) => JObject.FromObject(obj);
            }

            // TSrc --[Json]--> string --> TDest
            return((src, attr, context) =>
            {
                JObject jobj = funcJobj((object)src, attr, context);
                string json = jobj.ToString();
                TDest obj = fromString(json, attr, context);
                return obj;
            });
        }
Пример #6
0
        public Func <TSrc, TAttribute, TDest> GetConverter <TSrc, TDest, TAttribute>()
            where TAttribute : Attribute
        {
            // Give precedence to exact matches.
            // this lets callers override any other rules (like JSON binding)

            // TSrc --> TDest
            Func <TSrc, TAttribute, TDest> exactMatch = TryGetConverter <TSrc, TAttribute, TDest>();

            if (exactMatch != null)
            {
                return(exactMatch);
            }

            // Object --> TDest
            // Catch all for any conversion to TDest
            Func <object, TAttribute, TDest> objConversion = TryGetConverter <object, TAttribute, TDest>();

            if (objConversion != null)
            {
                return((src, attr) =>
                {
                    var result = objConversion(src, attr);
                    return result;
                });
            }

            // Inheritence (also covers idempotency)
            if (typeof(TDest).IsAssignableFrom(typeof(TSrc)))
            {
                return((src, attr) =>
                {
                    object obj = (object)src;
                    return (TDest)obj;
                });
            }

            // string --> TDest
            Func <string, TAttribute, TDest> fromString = TryGetConverter <string, TAttribute, TDest>();

            if (fromString == null)
            {
                return(null);
            }

            // String --> TDest
            if (typeof(TSrc) == typeof(string))
            {
                return((src, attr) =>
                {
                    var result = fromString((string)(object)src, attr);
                    return result;
                });
            }

            // Allow some well-defined intermediate conversions.
            // If this is "wrong" for your type, then it should provide an exact match to override.

            // Byte[] --[builtin]--> String --> TDest
            if (typeof(TSrc) == typeof(byte[]))
            {
                Func <byte[], TAttribute, string> bytes2string = TryGetConverter <byte[], TAttribute, string>();

                return((src, attr) =>
                {
                    byte[] bytes = (byte[])(object)src;
                    string str = bytes2string(bytes, attr);
                    var result = fromString(str, attr);
                    return result;
                });
            }

            // General JSON serialization rule.

            if (typeof(TSrc).IsPrimitive ||
                (typeof(TSrc) == typeof(object)) ||
                typeof(IEnumerable).IsAssignableFrom(typeof(TSrc)))
            {
                return(null);
            }

            // TSrc --[Json]--> string --> TDest
            return((src, attr) =>
            {
                string json = JsonConvert.SerializeObject(src);
                TDest obj = fromString(json, attr);
                return obj;
            });
        }