Skip to content

Commit 07ada7f

Browse files
authored
OfType Function (#253)
* wip * Comment unused code * Function AsType, Is, As and Cast * fix * fix * Resolve types by simple name #252 (#254) * SimpleName * add tests * solve code issue * fix code complexity * e != null * TypeFinder * . * add test
1 parent 4efa3d4 commit 07ada7f

23 files changed

+575
-143
lines changed

src-console/ConsoleAppEF2.0.2_InMemory/Program.cs

+6
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ public Type ResolveType(string typeName)
4141

4242
return ResolveType(assemblies, typeName);
4343
}
44+
45+
public Type ResolveTypeBySimpleName(string typeName)
46+
{
47+
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
48+
return ResolveTypeBySimpleName(assemblies, typeName);
49+
}
4450
}
4551

4652
private static IQueryable GetQueryable()

src-console/ConsoleAppEF2.0/Program.cs

+6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ public Type ResolveType(string typeName)
3030
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
3131
return ResolveType(assemblies, typeName);
3232
}
33+
34+
public Type ResolveTypeBySimpleName(string typeName)
35+
{
36+
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
37+
return ResolveTypeBySimpleName(assemblies, typeName);
38+
}
3339
}
3440

3541
private static IQueryable GetQueryable()

src-console/ConsoleAppEF2.1.1/Program.cs

+6
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ public Type ResolveType(string typeName)
3131

3232
return ResolveType(assemblies, typeName);
3333
}
34+
35+
public Type ResolveTypeBySimpleName(string typeName)
36+
{
37+
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
38+
return ResolveTypeBySimpleName(assemblies, typeName);
39+
}
3440
}
3541

3642
private static IQueryable GetQueryable()

src-console/ConsoleAppEF2.1.1_InMemory/Program.cs

+26-6
Original file line numberDiff line numberDiff line change
@@ -169,13 +169,13 @@ private static void LikeTests(TestContext context, ParsingConfig config)
169169
var dynamicCarsLike2 = context.Cars.Where(config, "TestContext.Like(Brand, \"%d%\")");
170170
Console.WriteLine("dynamicCarsLike2 {0}", JsonConvert.SerializeObject(dynamicCarsLike2, Formatting.Indented));
171171

172-
var dynamicFunctionsLike1 = context.Cars.Where(config, "DynamicFunctions.Like(Brand, \"%a%\")");
173-
Console.WriteLine("dynamicFunctionsLike1 {0}",
174-
JsonConvert.SerializeObject(dynamicFunctionsLike1, Formatting.Indented));
172+
//var dynamicFunctionsLike1 = context.Cars.Where(config, "DynamicFunctions.Like(Brand, \"%a%\")");
173+
//Console.WriteLine("dynamicFunctionsLike1 {0}",
174+
//JsonConvert.SerializeObject(dynamicFunctionsLike1, Formatting.Indented));
175175

176-
var dynamicFunctionsLike2 = context.Cars.Where(config, "DynamicFunctions.Like(Vin, \"%a.%b%\", \".\")");
177-
Console.WriteLine("dynamicFunctionsLike2 {0}",
178-
JsonConvert.SerializeObject(dynamicFunctionsLike2, Formatting.Indented));
176+
//var dynamicFunctionsLike2 = context.Cars.Where(config, "DynamicFunctions.Like(Vin, \"%a.%b%\", \".\")");
177+
//Console.WriteLine("dynamicFunctionsLike2 {0}",
178+
//JsonConvert.SerializeObject(dynamicFunctionsLike2, Formatting.Indented));
179179
}
180180

181181
private static void OfTypeAndCastTests(TestContext context, ParsingConfig config)
@@ -185,9 +185,29 @@ private static void OfTypeAndCastTests(TestContext context, ParsingConfig config
185185
var castDynamicWithString = context.BaseDtos.Where(b => b is TestDto).Cast(config, "ConsoleAppEF2.Database.TestDto").ToDynamicArray();
186186

187187
var oftype = context.BaseDtos.OfType<TestDto>().ToArray();
188+
bool ofTypeAny = context.BaseDtos.OfType<TestDto>().Any();
188189
var oftypeDynamicWithType = context.BaseDtos.OfType(typeof(TestDto)).ToDynamicArray();
189190
var oftypeDynamicWithString = context.BaseDtos.OfType(config, "ConsoleAppEF2.Database.TestDto").ToDynamicArray();
190191

192+
var configX = new ParsingConfig
193+
{
194+
ResolveTypesBySimpleName = true
195+
};
196+
var oftypeDynamicWithSimpleNameString = context.BaseDtos.OfType(configX, "TestDto").ToDynamicArray();
197+
198+
int isOfType = context.BaseDtos.Count(b => b is TestDto);
199+
int isOfTypeDynamicTestDto = context.BaseDtos.Count(config, "OfType(\"ConsoleAppEF2.Database.TestDto\")");
200+
int isOfTypeDynamicOtherTestDto = context.BaseDtos.Count(config, "OfType(\"ConsoleAppEF2.Database.OtherTestDto\")");
201+
int isOfTypeDynamicComplexDto = context.BaseDtos.Count(config, "OfType(\"ConsoleAppEF2.Database.ComplexDto\")");
202+
203+
var asOfType = context.BaseDtos.Where(b => b as TestDto != null).ToArray();
204+
var asOfTypeDynamicTestDto = context.BaseDtos.Where(config, "As(\"ConsoleAppEF2.Database.TestDto\") != null").ToDynamicArray();
205+
var asOfTypeDynamicOtherTestDto = context.BaseDtos.Where(config, "As(\"ConsoleAppEF2.Database.OtherTestDto\") != null").ToDynamicArray();
206+
var asOfTypeDynamicComplexDto = context.BaseDtos.Where(config, "As(\"ConsoleAppEF2.Database.ComplexDto\") != null").ToDynamicArray();
207+
208+
var castOnX = context.BaseDtos.Where(b => b as TestDto != null).Where(b => ((TestDto)b).Name != null).ToArray();
209+
var castOnXDynamic = context.BaseDtos.Where(b => b as TestDto != null).Where(config, "Cast(\"ConsoleAppEF2.Database.TestDto\").Name != null").ToArray();
210+
191211
var oftypeTestDto = context.BaseDtos.OfType<TestDto>().Where(x => x.Name == "t").ToArray();
192212
var oftypeTestDtoDynamic = context.BaseDtos.OfType<TestDto>().Where("Name == \"t\"").ToArray();
193213

src/System.Linq.Dynamic.Core/CustomTypeProviders/AbstractDynamicLinqCustomTypeProvider.cs

+29
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,35 @@ protected Type ResolveType([NotNull] IEnumerable<Assembly> assemblies, [NotNull]
4747
return null;
4848
}
4949

50+
/// <summary>
51+
/// Resolve a type by the simple name which is registered in the current application domain.
52+
/// </summary>
53+
/// <param name="assemblies">The assemblies to inspect.</param>
54+
/// <param name="simpleTypeName">The simple typename to resolve.</param>
55+
/// <returns>A resolved <see cref="Type"/> or null when not found.</returns>
56+
protected Type ResolveTypeBySimpleName([NotNull] IEnumerable<Assembly> assemblies, [NotNull] string simpleTypeName)
57+
{
58+
Check.NotNull(assemblies, nameof(assemblies));
59+
Check.NotEmpty(simpleTypeName, nameof(simpleTypeName));
60+
61+
foreach (var assembly in assemblies)
62+
{
63+
var fullnames = assembly.GetTypes().Select(t => t.FullName).Distinct();
64+
var firstMatchingFullname = fullnames.FirstOrDefault(fn => fn.EndsWith($".{simpleTypeName}"));
65+
66+
if (firstMatchingFullname != null)
67+
{
68+
Type resolvedType = assembly.GetType(firstMatchingFullname, false, true);
69+
if (resolvedType != null)
70+
{
71+
return resolvedType;
72+
}
73+
}
74+
}
75+
76+
return null;
77+
}
78+
5079
#if (WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
5180
/// <summary>
5281
/// Gets the assembly types annotated with <see cref="DynamicLinqTypeAttribute"/> in an Exception friendly way.

src/System.Linq.Dynamic.Core/CustomTypeProviders/DefaultDynamicLinqCustomTypeProvider.cs

+9
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ public Type ResolveType(string typeName)
5454
return ResolveType(assemblies, typeName);
5555
}
5656

57+
/// <inheritdoc cref="IDynamicLinkCustomTypeProvider.ResolveTypeBySimpleName"/>
58+
public Type ResolveTypeBySimpleName(string simpleTypeName)
59+
{
60+
Check.NotEmpty(simpleTypeName, nameof(simpleTypeName));
61+
62+
IEnumerable<Assembly> assemblies = _assemblyHelper.GetAssemblies();
63+
return ResolveTypeBySimpleName(assemblies, simpleTypeName);
64+
}
65+
5766
private HashSet<Type> GetCustomTypesInternal()
5867
{
5968
IEnumerable<Assembly> assemblies = _assemblyHelper.GetAssemblies();

src/System.Linq.Dynamic.Core/CustomTypeProviders/IDynamicLinkCustomTypeProvider.cs

+8-1
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,17 @@ public interface IDynamicLinkCustomTypeProvider
1515
HashSet<Type> GetCustomTypes();
1616

1717
/// <summary>
18-
/// Resolve any type which is registered in the current application domain.
18+
/// Resolve any type by fullname which is registered in the current application domain.
1919
/// </summary>
2020
/// <param name="typeName">The typename to resolve.</param>
2121
/// <returns>A resolved <see cref="Type"/> or null when not found.</returns>
2222
Type ResolveType([NotNull] string typeName);
23+
24+
/// <summary>
25+
/// Resolve any type by the simple name which is registered in the current application domain.
26+
/// </summary>
27+
/// <param name="simpleTypeName">The typename to resolve.</param>
28+
/// <returns>A resolved <see cref="Type"/> or null when not found.</returns>
29+
Type ResolveTypeBySimpleName([NotNull] string simpleTypeName);
2330
}
2431
}

src/System.Linq.Dynamic.Core/DynamicQueryableExtensions.cs

+7-14
Original file line numberDiff line numberDiff line change
@@ -229,10 +229,10 @@ public static IQueryable Cast([NotNull] this IQueryable source, [NotNull] Parsin
229229
Check.NotNull(config, nameof(config));
230230
Check.NotEmpty(typeName, nameof(typeName));
231231

232-
config.AllowNewToEvaluateAnyType = true;
233-
var newExpression = DynamicExpressionParser.ParseLambda(config, null, $"new {typeName}()");
232+
var finder = new TypeFinder(config, new KeywordsHelper(config));
233+
Type type = finder.FindTypeByName(typeName, null, true);
234234

235-
return Cast(source, newExpression.Body.Type);
235+
return Cast(source, type);
236236
}
237237

238238
/// <summary>
@@ -1025,10 +1025,10 @@ public static IQueryable OfType([NotNull] this IQueryable source, [NotNull] Pars
10251025
Check.NotNull(config, nameof(config));
10261026
Check.NotEmpty(typeName, nameof(typeName));
10271027

1028-
config.AllowNewToEvaluateAnyType = true;
1029-
var newExpression = DynamicExpressionParser.ParseLambda(config, null, $"new {typeName}()");
1028+
var finder = new TypeFinder(config, new KeywordsHelper(config));
1029+
Type type = finder.FindTypeByName(typeName, null, true);
10301030

1031-
return OfType(source, newExpression.Body.Type);
1031+
return OfType(source, type);
10321032
}
10331033

10341034
/// <summary>
@@ -2156,14 +2156,7 @@ private static TResult Execute<TResult>(MethodInfo operatorMethodInfo, IQueryabl
21562156

21572157
private static MethodInfo GetGenericMethod(string name)
21582158
{
2159-
try
2160-
{
2161-
return typeof(Queryable).GetTypeInfo().GetDeclaredMethods(name).Single(mi => mi.IsGenericMethod);
2162-
}
2163-
catch (Exception ex)
2164-
{
2165-
throw new Exception("Method not found: " + name, ex);
2166-
}
2159+
return typeof(Queryable).GetTypeInfo().GetDeclaredMethods(name).Single(mi => mi.IsGenericMethod);
21672160
}
21682161

21692162
private static MethodInfo GetMethod(string name, int parameterCount = 0, Func<MethodInfo, bool> predicate = null)

0 commit comments

Comments
 (0)