Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OfType Function #253

Merged
merged 6 commits into from
Feb 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src-console/ConsoleAppEF2.0.2_InMemory/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ public Type ResolveType(string typeName)

return ResolveType(assemblies, typeName);
}

public Type ResolveTypeBySimpleName(string typeName)
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
return ResolveTypeBySimpleName(assemblies, typeName);
}
}

private static IQueryable GetQueryable()
Expand Down
6 changes: 6 additions & 0 deletions src-console/ConsoleAppEF2.0/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ public Type ResolveType(string typeName)
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
return ResolveType(assemblies, typeName);
}

public Type ResolveTypeBySimpleName(string typeName)
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
return ResolveTypeBySimpleName(assemblies, typeName);
}
}

private static IQueryable GetQueryable()
Expand Down
6 changes: 6 additions & 0 deletions src-console/ConsoleAppEF2.1.1/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ public Type ResolveType(string typeName)

return ResolveType(assemblies, typeName);
}

public Type ResolveTypeBySimpleName(string typeName)
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
return ResolveTypeBySimpleName(assemblies, typeName);
}
}

private static IQueryable GetQueryable()
Expand Down
32 changes: 26 additions & 6 deletions src-console/ConsoleAppEF2.1.1_InMemory/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,13 +169,13 @@ private static void LikeTests(TestContext context, ParsingConfig config)
var dynamicCarsLike2 = context.Cars.Where(config, "TestContext.Like(Brand, \"%d%\")");
Console.WriteLine("dynamicCarsLike2 {0}", JsonConvert.SerializeObject(dynamicCarsLike2, Formatting.Indented));

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

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

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

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

var configX = new ParsingConfig
{
ResolveTypesBySimpleName = true
};
var oftypeDynamicWithSimpleNameString = context.BaseDtos.OfType(configX, "TestDto").ToDynamicArray();

int isOfType = context.BaseDtos.Count(b => b is TestDto);
int isOfTypeDynamicTestDto = context.BaseDtos.Count(config, "OfType(\"ConsoleAppEF2.Database.TestDto\")");
int isOfTypeDynamicOtherTestDto = context.BaseDtos.Count(config, "OfType(\"ConsoleAppEF2.Database.OtherTestDto\")");
int isOfTypeDynamicComplexDto = context.BaseDtos.Count(config, "OfType(\"ConsoleAppEF2.Database.ComplexDto\")");

var asOfType = context.BaseDtos.Where(b => b as TestDto != null).ToArray();
var asOfTypeDynamicTestDto = context.BaseDtos.Where(config, "As(\"ConsoleAppEF2.Database.TestDto\") != null").ToDynamicArray();
var asOfTypeDynamicOtherTestDto = context.BaseDtos.Where(config, "As(\"ConsoleAppEF2.Database.OtherTestDto\") != null").ToDynamicArray();
var asOfTypeDynamicComplexDto = context.BaseDtos.Where(config, "As(\"ConsoleAppEF2.Database.ComplexDto\") != null").ToDynamicArray();

var castOnX = context.BaseDtos.Where(b => b as TestDto != null).Where(b => ((TestDto)b).Name != null).ToArray();
var castOnXDynamic = context.BaseDtos.Where(b => b as TestDto != null).Where(config, "Cast(\"ConsoleAppEF2.Database.TestDto\").Name != null").ToArray();

var oftypeTestDto = context.BaseDtos.OfType<TestDto>().Where(x => x.Name == "t").ToArray();
var oftypeTestDtoDynamic = context.BaseDtos.OfType<TestDto>().Where("Name == \"t\"").ToArray();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,35 @@ protected Type ResolveType([NotNull] IEnumerable<Assembly> assemblies, [NotNull]
return null;
}

/// <summary>
/// Resolve a type by the simple name which is registered in the current application domain.
/// </summary>
/// <param name="assemblies">The assemblies to inspect.</param>
/// <param name="simpleTypeName">The simple typename to resolve.</param>
/// <returns>A resolved <see cref="Type"/> or null when not found.</returns>
protected Type ResolveTypeBySimpleName([NotNull] IEnumerable<Assembly> assemblies, [NotNull] string simpleTypeName)
{
Check.NotNull(assemblies, nameof(assemblies));
Check.NotEmpty(simpleTypeName, nameof(simpleTypeName));

foreach (var assembly in assemblies)
{
var fullnames = assembly.GetTypes().Select(t => t.FullName).Distinct();
var firstMatchingFullname = fullnames.FirstOrDefault(fn => fn.EndsWith($".{simpleTypeName}"));

if (firstMatchingFullname != null)
{
Type resolvedType = assembly.GetType(firstMatchingFullname, false, true);
if (resolvedType != null)
{
return resolvedType;
}
}
}

return null;
}

#if (WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
/// <summary>
/// Gets the assembly types annotated with <see cref="DynamicLinqTypeAttribute"/> in an Exception friendly way.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ public Type ResolveType(string typeName)
return ResolveType(assemblies, typeName);
}

/// <inheritdoc cref="IDynamicLinkCustomTypeProvider.ResolveTypeBySimpleName"/>
public Type ResolveTypeBySimpleName(string simpleTypeName)
{
Check.NotEmpty(simpleTypeName, nameof(simpleTypeName));

IEnumerable<Assembly> assemblies = _assemblyHelper.GetAssemblies();
return ResolveTypeBySimpleName(assemblies, simpleTypeName);
}

private HashSet<Type> GetCustomTypesInternal()
{
IEnumerable<Assembly> assemblies = _assemblyHelper.GetAssemblies();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,17 @@ public interface IDynamicLinkCustomTypeProvider
HashSet<Type> GetCustomTypes();

/// <summary>
/// Resolve any type which is registered in the current application domain.
/// Resolve any type by fullname which is registered in the current application domain.
/// </summary>
/// <param name="typeName">The typename to resolve.</param>
/// <returns>A resolved <see cref="Type"/> or null when not found.</returns>
Type ResolveType([NotNull] string typeName);

/// <summary>
/// Resolve any type by the simple name which is registered in the current application domain.
/// </summary>
/// <param name="simpleTypeName">The typename to resolve.</param>
/// <returns>A resolved <see cref="Type"/> or null when not found.</returns>
Type ResolveTypeBySimpleName([NotNull] string simpleTypeName);
}
}
21 changes: 7 additions & 14 deletions src/System.Linq.Dynamic.Core/DynamicQueryableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,10 @@ public static IQueryable Cast([NotNull] this IQueryable source, [NotNull] Parsin
Check.NotNull(config, nameof(config));
Check.NotEmpty(typeName, nameof(typeName));

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

return Cast(source, newExpression.Body.Type);
return Cast(source, type);
}

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

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

return OfType(source, newExpression.Body.Type);
return OfType(source, type);
}

/// <summary>
Expand Down Expand Up @@ -2156,14 +2156,7 @@ private static TResult Execute<TResult>(MethodInfo operatorMethodInfo, IQueryabl

private static MethodInfo GetGenericMethod(string name)
{
try
{
return typeof(Queryable).GetTypeInfo().GetDeclaredMethods(name).Single(mi => mi.IsGenericMethod);
}
catch (Exception ex)
{
throw new Exception("Method not found: " + name, ex);
}
return typeof(Queryable).GetTypeInfo().GetDeclaredMethods(name).Single(mi => mi.IsGenericMethod);
}

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