System.Linq.Dynamic.Core icon indicating copy to clipboard operation
System.Linq.Dynamic.Core copied to clipboard

Extension Method

Open gertcloete opened this issue 4 years ago • 3 comments

Hi,

I have written an implementation of IDynamicLinkCustomTypeProvider that load all my custom lynq functions:

When I use my DynamicLinqCustomTypeProvider I can use my Funcs.Left('asdfgh',3) fine as a expression, but unable to use Funcs.Left('asdfgh',3).Last()

Ie I am trying to make string extension methods that can be chained together. (Example below is just a simple one to show what I am trying to achieve) I have also noticed that GetExtensionMethods on DynamicLinqCustomTypeProvider is never called, but GetCustomTypes is called. Can you please help?

class DynamicLinqCustomTypeProvider : AbstractDynamicLinqCustomTypeProvider, IDynamicLinkCustomTypeProvider
{
public virtual HashSet GetCustomTypes() {...}
public Dictionary<Type, List> GetExtensionMethods() {...}
public Type ResolveType(string typeName) {...}
public Type ResolveTypeBySimpleName(string simpleTypeName) {...}
}

namespace Expressions
{
[DynamicLinqType]
public static class Funcs
{
public static string Left(object text, int numChars)
{
return Left(text as string, numChars);
}
public static string Last(this string input)
{
return input.Substring(str.Length - 1);
}
}
}

To explain the requirement, we are trying to use the dynamic lynq in the following scenario. Below is the way it work currently, but the bottom example is how I would like to use it. Hence I would like to make extension methods evaluate also. IE I have an custom method: Funcs.Split(...) that return a string[] and then a extension custom method that work in string[] and can join then ie Funcs.TextJoin(...)

In practice we will not Split and TextJoin like the unit test below, as the extension method we want to make is more complicated. The below was just to proof out one can make extension methods, that can be used in the dynamic lynq parser.

[Test]
public async Task Expression_with_textleft_and_last()
{
        dynamic row = new ExpandoObject();
        row.Address = "12 Church Street, Washington,United States";

        string returnValue = _expressionEvalutator.Evaluate<string>(row, "Funcs.TextJoin(\"|\", (Funcs.Split(\",\", Address)))");

        Assert.AreEqual("12 Church Street| Washington|United States", returnValue);
}

[Test]
public async Task Expression_with_textsplit_on_comma_and_join_by_pipe_ext()
{
       dynamic row = new ExpandoObject();
       row.Address = "12 Church Street, Washington,United States";

        string returnValue = _expressionEvalutator.Evaluate<string>(row, "Funcs.Split(\",\", Address).TextJoin(\"|\")");

        Assert.AreEqual("12 Church Street| Washington|United States", returnValue);
}

gertcloete avatar Nov 05 '21 09:11 gertcloete

@gertcloete Extension method support is present. See

  • https://github.com/zzzprojects/System.Linq.Dynamic.Core/blob/master/test/System.Linq.Dynamic.Core.Tests/Parser/DynamicLinqTypeTest.cs#L164
  • https://github.com/zzzprojects/System.Linq.Dynamic.Core/blob/master/test/System.Linq.Dynamic.Core.Tests/Parser/DynamicLinqTypeTest.cs#L175

StefH avatar Aug 08 '23 16:08 StefH

Hello @gertcloete, does my answer solve your issue?

StefH avatar Sep 10 '23 09:09 StefH

Hello @gertcloete, does my answer solve your issue?

StefH avatar Dec 05 '23 18:12 StefH