.NET Portable TypeCast  3.1.0.4
A, easy-to-use tested, generic, portable, runtime-extensible, arbitrary type converter library
ConverterExtension.cs
Go to the documentation of this file.
1 // <copyright file=mitlicense.md url=http://lsauer.mit-license.org/ >
2 // Lo Sauer, 2013-2016
3 // </copyright>
4 // <summary> A tested, generic, portable, runtime-extensible type converter library </summary
5 // <language> C# > 6.0 </language>
6 // <version> 3.1.0.2 </version>
7 // <author> Lorenz Lo Sauer; people credited in the sources </author>
8 // <project> https://github.com/lsauer/dotnet-portable-type-cast </project>
9 namespace Core.TypeCast
10 {
11  using System;
12  using System.Linq;
13  using System.Reflection;
14 
15  using Core.TypeCast.Base;
16 
20  public static class ConverterExtension
21  {
42  public static Func<TIn, TOut, TOut> FunctionDefaultWrapper<TIn, TOut>(this Converter self)
43  {
44  if (self.Function == null)
45  {
46  return null;
47  }
48  Func<TIn, TOut> converter = (Func<TIn, TOut>)self.Function;
49  Func<TIn, TOut, TOut> converterDefault = (value, defaultValue) =>
50  {
51  TOut retvalue = default(TOut);
52  try
53  {
54  var result = converter(value);
55  retvalue = Equals(default(TOut), result) == true ? defaultValue : result;
56  }
57  catch (Exception exc)
58  {
59  throw new ConverterException(ConverterCause.ConverterWrapperError, exc);
60  }
61  return retvalue;
62  };
63  return converterDefault;
64  }
65 
76  public static Func<TIn, TOut, TOut> FunctionDefaultWrapper<TIn, TOut>(this Converter<TIn, TOut> self)
77  {
78  return (self as Converter)?.FunctionDefaultWrapper<TIn, TOut>();
79  }
80 
89  public static bool MergeStandard(this Converter self, Converter converter)
90  {
91  // check that either converter has a Function and DefaultFunction set
92  if(self != null && self.Standard == true)
93  {
94  if((self.HasFunction == converter.HasFunction) && (self.HasDefaultFunction == converter.HasDefaultFunction))
95  {
96  throw new ConverterCollectionException(ConverterCollectionCause.ConverterExists, self.ToString());
97  }
98 
99  // merge the two converters together by using the existing and discarding the other
100  if(self.HasDefaultFunction == false)
101  {
102  self.FunctionDefault = converter.FunctionDefault;
103  }
104  else
105  {
106  self.Function = converter.Function;
107  }
108 
109  self.Attribute = self.Attribute ?? converter.Attribute;
110  return true;
111  }
112  return false;
113  }
114 
121  public static bool SetCollectionDefaults(this Converter self, ConverterCollection collection = null)
122  {
123  if(collection != null)
124  {
125  // add a collection reference to the converter
126  self.Collection = collection;
127  }
128 
129  if(self.Collection == null)
130  {
131  // set common collection settings according to the ConverterCollectionSettings
132  self.DefaultValueAnyType |= self.Collection.Settings.DefaultValueAnyType;
133  self.UseFunctionDefaultWrapper |= self.Collection.Settings.UseFunctionDefaultWrapper;
134  return true;
135  }
136  return false;
137  }
138 
144  public static void SetBaseType(this Converter self, Type baseType)
145  {
146  if(self.BaseType == null && baseType != null)
147  {
148  self.BaseType = baseType.GetTypeInfo();
149  }
150  else if(self.BaseType == null && baseType == null && self.HasFunction)
151  {
152  self.BaseType = ((self.Function ?? self.FunctionDefault) as Delegate)?
153  .Target
154  .GetType()
155  .DeclaringType
156  .GetTypeInfo();
157  }
158  }
159 
165  public static IQueryable<Converter> WithSameFromType(this Converter self)
166  {
167  if(self.Collection != null)
168  {
169  return self.Collection.Items.AsQueryable().WithFrom(self.From);
170  }
171  return null;
172  }
173 
179  public static IQueryable<Converter> WithSameToType(this Converter self)
180  {
181  if(self.Collection != null)
182  {
183  return self.Collection.Items.AsQueryable().WithTo(self.To);
184  }
185  return null;
186  }
187 
196  public static void MergeFromMethodAttribute(this Converter self, MethodInfo methodInfo)
197  {
198  var classAttribute = methodInfo.DeclaringType.GetTypeInfo().GetCustomAttribute<ConverterAttribute>();
199  var methodAttribute = methodInfo.GetCustomAttribute<ConverterMethodAttribute>();
200 
201  // set function-alias for unique transformation function lookup
202  self.Attribute = new ConverterAttribute(loadOnDemand: classAttribute?.LoadOnDemand ?? false,
203  name: String.IsNullOrWhiteSpace(classAttribute?.Name) ? methodAttribute?.Name : classAttribute.Name,
204  nameSpace: methodInfo.DeclaringType.Namespace,
205  dependencyInjection: classAttribute?.DependencInjection ?? false);
206 
207  // set base-type delegate type used for unique transformation-lookup
208  if(methodAttribute?.BaseType != null)
209  {
210  self.BaseType = self.BaseType ?? methodAttribute.BaseType.GetTypeInfo();
211  }
212  }
213  }
214 }
ConverterCollectionCause
Contains the reasons for a ConverterCollectionException to be raised.
ConverterCause
Contains the reasons for a ConverterException to be raised.