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; }); }
/// <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()); }
/// <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; }); }
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; }); }
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; }); }