I haven't used System.Linq.Dynamic
a lot, but here is a way to make your example work:
1 - You really only have one input object, your EventListItem
, so remove parameter2 (Regex):
string compilableExpression = "Regex.IsMatch(Category.ToLower(), \"\\bSomeCat\\b\", RegexOptions.Compiled) == true";
ParameterExpression parameter1 = System.Linq.Expressions.Expression.Parameter(typeof(EventListItem));
return System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] { parameter1 }, null, compilableExpression);
2 - DynamicExpression.ParseLambda()
is made to read properties and methods from the input object. Using methods on other classes (here: Regex.IsMatch()
is limited to a small set of predefined classes, and by default Regex
isn't one of them.
Therefore, we somehow need to make the parser realize that "Regex" is a class and not a property on EventListItem. Assuming you have included the DynamicLinq.cs file in your project, this can be done by adding Regex (and RegexOptions) to the internal ExpressionParser.predefinedTypes
array:
static readonly Type[] predefinedTypes = {
typeof(Object),
typeof(Boolean),
...
typeof(System.Text.RegularExpressions.Regex),
typeof(System.Text.RegularExpressions.RegexOptions),
};
EDIT: Complex parameter values
If we need to include more complex parameters in our method calls, e.g. a combined RegexOptions enum; RegexOptions.Compiled | RegexOptions.IgnoreCase
, ParseLambda also accepts a list of values
.
We prepare the combined enum beforehand, and submit it in that values list. In compilableExpression
we include placeholders for the values we submit, indexed in the same order we submit them (here we only have one value - index 0)
var options = RegexOptions.Compiled | RegexOptions.IgnoreCase;
string compilableExpression = "Regex.IsMatch(Category.ToLower(), \"\\bSomeCat\\b\", @0) == true";
ParameterExpression parameter1 = SLE.Expression.Parameter(typeof(EventListItem));
return SLD.DynamicExpression.ParseLambda(new[] { parameter1 },
null,
compilableExpression,
options);
Bonus: Because the RegexOptions class/enum is no longer directly referenced in compilableExpression, we also no longer need to include RegexOptions in ExpressionParser.predefinedTypes.