Skip to content
8 changes: 7 additions & 1 deletion src-console/ConsoleAppEF2.0.2_InMemory/Program.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Dynamic.Core.CustomTypeProviders;
Expand All @@ -25,6 +24,13 @@ public HashSet<Type> GetCustomTypes()

return set;
}

public Type ResolveType(string typeName)
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();

return ResolveType(assemblies, typeName);
}
}

private static IQueryable GetQueryable()
Expand Down
7 changes: 7 additions & 0 deletions src-console/ConsoleAppEF2.0/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Linq.Dynamic.Core;
using System.Linq.Dynamic.Core.CustomTypeProviders;
using ConsoleAppEF2.Database;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;

Expand All @@ -23,6 +24,12 @@ public HashSet<Type> GetCustomTypes()

return set;
}

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

private static IQueryable GetQueryable()
Expand Down
8 changes: 8 additions & 0 deletions src-console/ConsoleAppEF2.1.1/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Linq.Dynamic.Core;
using System.Linq.Dynamic.Core.CustomTypeProviders;
using ConsoleAppEF2.Database;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;

Expand All @@ -23,6 +24,13 @@ public HashSet<Type> GetCustomTypes()

return set;
}

public Type ResolveType(string typeName)
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();

return ResolveType(assemblies, typeName);
}
}

private static IQueryable GetQueryable()
Expand Down
35 changes: 30 additions & 5 deletions src-console/ConsoleAppEF2.1.1_InMemory/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,17 @@ namespace ConsoleAppEF2
{
static class Program
{
class C : AbstractDynamicLinqCustomTypeProvider, IDynamicLinkCustomTypeProvider
public class NestedDto
{
public string Name { get; set; }

public class NestedDto2
{
public string Name2 { get; set; }
}
}

class NetCore21CustomTypeProvider : AbstractDynamicLinqCustomTypeProvider, IDynamicLinkCustomTypeProvider
{
public HashSet<Type> GetCustomTypes()
{
Expand All @@ -26,6 +36,12 @@ public HashSet<Type> GetCustomTypes()

return set;
}

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

private static object GetObj()
Expand Down Expand Up @@ -150,6 +166,18 @@ private static TResult Execute<TResult>(MethodInfo operatorMethodInfo, IQueryabl

static void Main(string[] args)
{
var config = new ParsingConfig
{
AllowNewToEvaluateAnyType = true,
CustomTypeProvider = new NetCore21CustomTypeProvider()
};

// Act
var testDataAsQueryable = new List<string>() { "name1", "name2" }.AsQueryable();
var projectedData = (IQueryable<NestedDto>)testDataAsQueryable.Select(config, $"new {typeof(NestedDto).FullName}(~ as Name)");
Console.WriteLine(projectedData.First().Name);
Console.WriteLine(projectedData.Last().Name);

IQueryable qry = GetQueryable();

var result = qry.Select("it").OrderBy("Value");
Expand Down Expand Up @@ -183,10 +211,7 @@ static void Main(string[] args)
var any2 = anyTest.Where("values.Contains(1)");
Console.WriteLine("any2 {0}", JsonConvert.SerializeObject(any2, Formatting.Indented));

var config = new ParsingConfig
{
CustomTypeProvider = new C()
};


var dateLastModified = new DateTime(2018, 1, 15);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<Description>Dynamic Linq extensions for EntityFramework which adds Async support</Description>
<AssemblyTitle>EntityFramework.DynamicLinq</AssemblyTitle>
<VersionPrefix>1.0.8.18</VersionPrefix>
<VersionPrefix>1.0.9.1</VersionPrefix>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net45;net46</TargetFrameworks>
<DefineConstants>EF</DefineConstants>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<Description>Dynamic Linq extensions for Microsoft.EntityFrameworkCore which adds Async support</Description>
<AssemblyTitle>Microsoft.EntityFrameworkCore.DynamicLinq</AssemblyTitle>
<VersionPrefix>1.0.8.18</VersionPrefix>
<VersionPrefix>1.0.9.1</VersionPrefix>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net451;net46;netstandard1.3;netstandard2.0;uap10.0</TargetFrameworks>
<DefineConstants>$(DefineConstants);EFCORE</DefineConstants>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace System.Linq.Dynamic.Core.CustomTypeProviders
{
/// <summary>
/// The abstract <see cref="AbstractDynamicLinqCustomTypeProvider"/>. Find all types marked with <see cref="DynamicLinqTypeAttribute"/>.
/// The abstract DynamicLinqCustomTypeProvider which is used by the <see cref="IDynamicLinkCustomTypeProvider"/> and can be used by a custom TypeProvider like in .NET Core.
/// </summary>
public abstract class AbstractDynamicLinqCustomTypeProvider
{
Expand All @@ -30,6 +30,29 @@ protected IEnumerable<Type> FindTypesMarkedWithDynamicLinqTypeAttribute([NotNull
#endif
}

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

foreach (Assembly assembly in assemblies)
{
Type resolvedType = assembly.GetType(typeName, false, true);
if (resolvedType != null)
{
return resolvedType;
}
}

return null;
}

#if (WINDOWS_APP || DOTNET5_1 || UAP10_0 || NETSTANDARD)
/// <summary>
/// Gets the assembly types in an Exception friendly way.
Expand All @@ -48,8 +71,10 @@ protected IEnumerable<TypeInfo> GetAssemblyTypes([NotNull] IEnumerable<Assembly>
{
definedTypes = assembly.DefinedTypes;
}
catch (Exception)
{ }
catch
{
// Ignore error
}

if (definedTypes != null)
{
Expand Down Expand Up @@ -78,8 +103,10 @@ protected IEnumerable<Type> GetAssemblyTypes([NotNull] IEnumerable<Assembly> ass
{
definedTypes = assembly.GetTypes();
}
catch (Exception)
{ }
catch
{
// Ignore error
}

if (definedTypes != null)
{
Expand All @@ -92,4 +119,4 @@ protected IEnumerable<Type> GetAssemblyTypes([NotNull] IEnumerable<Assembly> ass
}
#endif
}
}
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,36 @@
#if !(WINDOWS_APP || UAP10_0)
using System.Collections.Generic;
using System.Linq.Dynamic.Core.Validation;
using System.Reflection;

namespace System.Linq.Dynamic.Core.CustomTypeProviders
{
/// <summary>
/// The default <see cref="IDynamicLinkCustomTypeProvider"/>. Scans the current AppDomain for all types marked with <see cref="DynamicLinqTypeAttribute"/>, and adds them as custom Dynamic Link types.
/// The default <see cref="IDynamicLinkCustomTypeProvider"/>.
/// Scans the current AppDomain for all types marked with <see cref="DynamicLinqTypeAttribute"/>, and adds them as custom Dynamic Link types.
///
/// Also provides functionality to resolve a Type in the current Application Domain.
///
/// This class is used as default for full .NET Framework, so not for .NET Core
/// </summary>
public class DefaultDynamicLinqCustomTypeProvider : AbstractDynamicLinqCustomTypeProvider, IDynamicLinkCustomTypeProvider
{
private readonly IAssemblyHelper _assemblyHelper = new DefaultAssemblyHelper();
private HashSet<Type> _customTypes;

/// <summary>
/// Returns a list of custom types that System.Linq.Dynamic.Core will understand.
/// </summary>
/// <returns>
/// A <see cref="System.Collections.Generic.HashSet&lt;Type&gt;" /> list of custom types.
/// </returns>
/// <inheritdoc cref="IDynamicLinkCustomTypeProvider.GetCustomTypes"/>
public virtual HashSet<Type> GetCustomTypes()
{
if (_customTypes != null)
{
return _customTypes;
}
IEnumerable<Assembly> assemblies = _assemblyHelper.GetAssemblies();
return new HashSet<Type>(FindTypesMarkedWithDynamicLinqTypeAttribute(assemblies));
}

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

IEnumerable<Assembly> assemblies = _assemblyHelper.GetAssemblies();
_customTypes = new HashSet<Type>(FindTypesMarkedWithDynamicLinqTypeAttribute(assemblies));
return _customTypes;
return ResolveType(assemblies, typeName);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Collections.Generic;
using JetBrains.Annotations;

namespace System.Linq.Dynamic.Core.CustomTypeProviders
{
/// <summary>
/// Interface for providing functionality to find custom types for or resolve any type.
/// </summary>
public interface IDynamicLinkCustomTypeProvider
{
/// <summary>
/// Returns a list of custom types that System.Linq.Dynamic.Core will understand.
/// </summary>
/// <returns>A <see cref="HashSet&lt;Type&gt;" /> list of custom types.</returns>
HashSet<Type> GetCustomTypes();

/// <summary>
/// Resolve any type 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);
}
}

This file was deleted.

2 changes: 1 addition & 1 deletion src/System.Linq.Dynamic.Core/DynamicQueryableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ public static IQueryable GroupJoin([NotNull] this IQueryable outer, [CanBeNull]
typeof(Queryable), nameof(Queryable.GroupJoin),
new[] { outer.ElementType, innerType, outerSelectorLambda.Body.Type, resultSelectorLambda.Body.Type },
outer.Expression,
Expression.Constant(inner),
inner.AsQueryable().Expression,
Expression.Quote(outerSelectorLambda),
Expression.Quote(innerSelectorLambda),
Expression.Quote(resultSelectorLambda)));
Expand Down
10 changes: 10 additions & 0 deletions src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1525,14 +1525,17 @@ Type FindType(string name)
{
return result;
}

if (_it != null && _it.Type.Name == name)
{
return _it.Type;
}

if (_parent != null && _parent.Type.Name == name)
{
return _parent.Type;
}

if (_root != null && _root.Type.Name == name)
{
return _root.Type;
Expand All @@ -1541,15 +1544,22 @@ Type FindType(string name)
{
return _it.Type;
}

if (_parent != null && _parent.Type.Namespace + "." + _parent.Type.Name == name)
{
return _parent.Type;
}

if (_root != null && _root.Type.Namespace + "." + _root.Type.Name == name)
{
return _root.Type;
}

if (_parsingConfig.AllowNewToEvaluateAnyType && _parsingConfig.CustomTypeProvider != null)
{
return _parsingConfig.CustomTypeProvider.ResolveType(name);
}

return null;
}

Expand Down
5 changes: 5 additions & 0 deletions src/System.Linq.Dynamic.Core/ParsingConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,10 @@ public IDynamicLinkCustomTypeProvider CustomTypeProvider
/// See https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-2.1#linq-groupby-translation
/// </summary>
public bool EvaluateGroupByAtDatabase { get; set; }

/// <summary>
/// Allows the New() keyword to evaluate any available Type.
/// </summary>
public bool AllowNewToEvaluateAnyType { get; set; } = false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<Description>This is a .NETStandard/ .NET Core port of the the Microsoft assembly for the .Net 4.0 Dynamic language functionality.</Description>
<AssemblyTitle>System.Linq.Dynamic.Core</AssemblyTitle>
<VersionPrefix>1.0.8.18</VersionPrefix>
<VersionPrefix>1.0.9.1</VersionPrefix>
<Authors>Microsoft;Scott Guthrie;King Wilder;Nathan Arnott;Stef Heyenrath</Authors>
<TargetFrameworks>net35;net40;net45;net46;netstandard1.3;netstandard2.0;uap10.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ public HashSet<Type> GetCustomTypes()
return new HashSet<Type>(FindTypesMarkedWithDynamicLinqTypeAttribute(assemblies));
}

public Type ResolveType(string typeName)
{
var assemblies = GetAssemblyListAsync().Result;
return ResolveType(assemblies, typeName);
}

private static async Task<List<Assembly>> GetAssemblyListAsync()
{
List<Assembly> assemblies = new List<Assembly>();
Expand Down
Loading