9 namespace Core.TypeCast
12 using System.Collections;
13 using System.Collections.Concurrent;
14 using System.Collections.Generic;
15 using System.Globalization;
17 using System.Linq.Expressions;
18 using System.Reflection;
19 using System.Runtime.CompilerServices;
20 using System.Runtime.InteropServices;
21 using System.Threading;
30 public static class ConverterCollectionFilters
32 private static TypeInfo objectTypeInfo = typeof(
object).GetTypeInfo();
33 private static TypeInfo convertContexTypeInfo = typeof(IConvertContext).GetTypeInfo();
42 [MethodImpl(MethodImplOptions.AggressiveInlining)]
43 public static IQueryable<Converter> WithFrom(
this IQueryable<Converter> query, TypeInfo typeFrom,
bool assignable =
false)
47 query = WithAssignable(query, c => c.From == typeFrom, c => c.From.IsSuperOrSubType(typeFrom), typeFrom, assignable);
59 [MethodImpl(MethodImplOptions.AggressiveInlining)]
60 public static IQueryable<Converter> WithFrom(
this IQueryable<Converter> query, Type typeFrom,
bool assignable =
false)
62 return WithFrom(query, typeFrom?.GetTypeInfo(), assignable);
72 [MethodImpl(MethodImplOptions.AggressiveInlining)]
73 public static IQueryable<Converter> WithTo(
this IQueryable<Converter> query, TypeInfo typeTo,
bool assignable =
false)
77 query = WithAssignable(query, c => c.To == typeTo, c => c.To.IsSuperOrSubType(typeTo), typeTo, assignable);
89 [MethodImpl(MethodImplOptions.AggressiveInlining)]
90 public static IQueryable<Converter> WithTo(
this IQueryable<Converter> query, Type typeTo,
bool assignable =
false)
92 return WithTo(query, typeTo?.GetTypeInfo(), assignable);
102 [MethodImpl(MethodImplOptions.AggressiveInlining)]
103 public static IQueryable<Converter> WithBaseType(
this IQueryable<Converter> query, TypeInfo typeBase,
bool assignable =
false)
105 if(typeBase != null && typeBase.AsType() != typeof(
object))
107 query = WithAssignable(query, c => c.BaseType == typeBase, c => c.BaseType.IsSuperOrSubType(typeBase), typeBase, assignable);
119 [MethodImpl(MethodImplOptions.AggressiveInlining)]
120 public static IQueryable<Converter> WithBaseType(
this IQueryable<Converter> query, Type typeBase,
bool assignable =
false)
122 return WithBaseType(query, typeBase?.GetTypeInfo(), assignable);
134 [MethodImpl(MethodImplOptions.AggressiveInlining)]
135 public static IQueryable<Converter> WithArgument(
this IQueryable<Converter> query, TypeInfo typeArgument,
bool assignable =
false,
bool withContext =
false)
138 if(withContext ==
true)
140 query = query.Where(c => c.Argument == objectTypeInfo || c.Argument.IsSuperOrSubType(convertContexTypeInfo));
142 else if(typeArgument != null && (assignable ==
false || typeArgument != objectTypeInfo))
144 query = WithAssignable(query, c => c.Argument == typeArgument, c => c.Argument.IsSuperOrSubType(typeArgument), typeArgument, assignable);
159 [MethodImpl(MethodImplOptions.AggressiveInlining)]
160 public static IQueryable<Converter> WithArgument(
this IQueryable<Converter> query, Type typeArgument,
bool assignable =
true,
bool withContext =
false)
162 return WithArgument(query, typeArgument?.GetTypeInfo(), assignable, withContext);
176 [MethodImpl(MethodImplOptions.AggressiveInlining)]
177 private static IQueryable<Converter> WithAssignable(IQueryable<Converter> query, Expression<Func<Converter, bool>> predicate, Expression<Func<Converter, bool>> predicateAssignable, TypeInfo type,
bool assignable)
179 var testQuery = query.Where(predicate);
180 if((type == objectTypeInfo || testQuery.Any()) && assignable ==
false)
187 query = query.Where(predicateAssignable);
198 [MethodImpl(MethodImplOptions.AggressiveInlining)]
199 public static IQueryable<Converter> WithStandard(
this IQueryable<Converter> query,
bool? isStandard =
true)
201 if(isStandard != null)
203 query = query.Where(c => c.Standard == isStandard);
216 [MethodImpl(MethodImplOptions.AggressiveInlining)]
217 public static IQueryable<Converter> WithFromIsGenericType(
this IQueryable<Converter> query,
bool? typeFromIsGenericType =
true)
219 if(typeFromIsGenericType != null)
221 query = query.Where(c => c.From.IsGenericType == typeFromIsGenericType);
233 [MethodImpl(MethodImplOptions.AggressiveInlining)]
234 public static IQueryable<Converter> WithToIsGenericType(
this IQueryable<Converter> query,
bool? typeToIsGenericType =
true)
236 if(typeToIsGenericType != null)
238 query = query.Where(c => c.From.IsGenericType == typeToIsGenericType);
251 [MethodImpl(MethodImplOptions.AggressiveInlining)]
252 public static IQueryable<Converter> WithFunctionName(
this IQueryable<Converter> query,
string containedName = null)
254 if(containedName != null)
256 query = query.Where(c => (c.Function != null && (c.Function as Delegate).GetMethodInfo().Name.Contains(containedName) ==
true) ||
257 (c.FunctionDefault != null && (c.FunctionDefault as Delegate).GetMethodInfo().Name.Contains(containedName) ==
true)
271 [MethodImpl(MethodImplOptions.AggressiveInlining)]
272 public static IQueryable<Converter> WithConverterAttributeName(
this IQueryable<Converter> query,
string containedName = null,
bool caseSensitive =
false)
274 if(
string.IsNullOrWhiteSpace(containedName) ==
false)
276 if(caseSensitive ==
true)
278 query = query.Where(c => (c.Attribute != null && c.Attribute.Name.ToLowerInvariant().Equals(containedName.ToLowerInvariant()) ==
true));
282 query = query.Where(c => (c.Attribute != null && c.Attribute.Name.Equals(containedName) ==
true));
294 [MethodImpl(MethodImplOptions.AggressiveInlining)]
295 public static IQueryable<Converter> WithDefaultFunction(
this IQueryable<Converter> query,
bool? hasDefaultFunction =
true)
297 if(hasDefaultFunction != null)
299 query = query.Where(c => c.HasDefaultFunction == hasDefaultFunction);
323 public static IQueryable<Converter> ApplyAllFilters(
324 this IQueryable<Converter> query,
325 TypeInfo typeFrom = null,
326 TypeInfo typeTo = null,
327 TypeInfo typeArgument = null,
328 TypeInfo typeBase = null,
329 bool? hasDefaultFunction = null,
330 bool? isStandard = null,
331 bool? typeFromIsGenericType = null,
332 bool? typeToIsGenericType = null,
333 string functionName = null,
334 string attributeName = null,
335 bool assignableFrom =
false,
336 bool assignableTo =
false,
337 bool assignableArgument =
false,
338 bool assignableBaseType =
false,
339 bool withContext =
false)
341 var queryFiltered = query
342 .WithFrom(typeFrom, assignableFrom)
343 .WithTo(typeTo, assignableTo)
344 .WithArgument(typeArgument, assignableArgument, withContext)
345 .WithBaseType(typeBase, assignableBaseType)
346 .WithStandard(isStandard)
347 .WithDefaultFunction(hasDefaultFunction)
348 .WithFromIsGenericType(typeFromIsGenericType)
349 .WithToIsGenericType(typeToIsGenericType)
350 .WithFunctionName(functionName)
351 .WithConverterAttributeName(attributeName);
354 if(typeBase == null && queryFiltered.Count() > 1)
356 typeArgument = typeArgument ?? objectTypeInfo;
358 queryFiltered = queryFiltered.WithArgument(typeArgument, assignableArgument);
360 return queryFiltered;