├── .hgignore
├── Mindbox.Expressions
├── Evaluators
│ ├── IExpressionEvaluator.cs
│ ├── InterpretingExpressionEvaluator.cs
│ ├── CompilingExpressionEvaluator.cs
│ └── Caching
│ │ ├── ClosureCapturedValuesVisitor.cs
│ │ ├── ClosureCapturedValuesProvider.cs
│ │ ├── ClosureCapturedValuesParametrizer.cs
│ │ ├── CachingCompilingExpressionEvaluator.cs
│ │ └── MindboxExpressionStringBuilder.cs
├── ExpressionsConfiguration.cs
├── AssemblyInfo.cs
├── ExpressionFunctions
│ ├── ExpressionFunction.cs
│ └── ExpressionFunctionFactory.cs
├── Mindbox.Expressions.csproj
├── ExpressionParameterPresenceDetector.cs
├── EvaluationScope.cs
├── ExpressionParameterSubstitutor.cs
├── ExpressionExpander.cs
├── ExpressionVisitor.cs
└── ReflectionExpressions.cs
├── Mindbox.Expressions.Tests
├── packages.config
├── AssertException.cs
├── Mindbox.Expressions.Tests.csproj
├── ExpressionFunctionTests.cs
├── EvaluationScopeTests.cs
├── EvaluateTests.cs
├── ReflectionExpressionsTests.cs
├── BooleanExpressionsTests.cs
└── ExpandExpressionTests.cs
├── README.md
├── .github
└── workflows
│ ├── pull-request.yml
│ └── publish.yml
├── LICENSE
├── Mindbox.Expressions.sln
├── package.cmd
└── .gitignore
/.hgignore:
--------------------------------------------------------------------------------
1 | syntax: glob
2 | *.suo
3 | obj
4 | bin
5 | .git
6 | TestResults
7 | packages
8 |
--------------------------------------------------------------------------------
/Mindbox.Expressions/Evaluators/IExpressionEvaluator.cs:
--------------------------------------------------------------------------------
1 | using System.Linq.Expressions;
2 |
3 | namespace Mindbox.Expressions
4 | {
5 | public interface IExpressionEvaluator
6 | {
7 | object Evaluate(Expression expression);
8 | }
9 | }
--------------------------------------------------------------------------------
/Mindbox.Expressions.Tests/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | expressions
2 | ===========
3 |
4 | Allows to include lambda expressions into each other in c# and Visual Basic. Also allows to avoid using string constants in reflection thus enabling easy refactoring.
5 |
6 | See wiki at https://github.com/mindbox-cloud/expressions/wiki
7 |
--------------------------------------------------------------------------------
/Mindbox.Expressions/ExpressionsConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Mindbox.Expressions
4 | {
5 | public static class ExpressionsConfiguration
6 | {
7 | public static Func ExpressionEvaluatorFactory { get; set; } =
8 | () => CompilingExpressionEvaluator.Instance;
9 | }
10 | }
--------------------------------------------------------------------------------
/Mindbox.Expressions/Evaluators/InterpretingExpressionEvaluator.cs:
--------------------------------------------------------------------------------
1 | using System.Linq.Expressions;
2 |
3 | namespace Mindbox.Expressions
4 | {
5 | public class InterpretingExpressionEvaluator : IExpressionEvaluator
6 | {
7 | public object Evaluate(Expression expression)
8 | {
9 | return EvaluationScope.Empty.TryEvaluate(expression);
10 | }
11 |
12 | public static InterpretingExpressionEvaluator Instance { get; } = new InterpretingExpressionEvaluator();
13 | }
14 | }
--------------------------------------------------------------------------------
/Mindbox.Expressions/Evaluators/CompilingExpressionEvaluator.cs:
--------------------------------------------------------------------------------
1 | using System.Linq.Expressions;
2 |
3 | namespace Mindbox.Expressions
4 | {
5 | public class CompilingExpressionEvaluator : IExpressionEvaluator
6 | {
7 | public object Evaluate(Expression expression)
8 | {
9 | return Expression.Lambda(expression).Compile()
10 | .DynamicInvoke();
11 | }
12 |
13 | public static CompilingExpressionEvaluator Instance { get; } = new CompilingExpressionEvaluator();
14 | }
15 | }
--------------------------------------------------------------------------------
/Mindbox.Expressions/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | [assembly: AssemblyTitle("Mindbox.Expressions")]
5 | [assembly: AssemblyCompany("Mindbox")]
6 | [assembly: AssemblyProduct("Mindbox.Expressions")]
7 | [assembly: AssemblyDescription("Allows to include lambda expressions into each other in c# and Visual Basic. " +
8 | "Also allows to avoid using string constants in reflection thus enabling easy refactoring.")]
9 | [assembly: AssemblyCopyright("Copyright © Mindbox 2014")]
10 | [assembly: AssemblyVersion("3.0.1")]
11 |
--------------------------------------------------------------------------------
/Mindbox.Expressions/ExpressionFunctions/ExpressionFunction.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Mindbox.Expressions
5 | {
6 | internal class ExpressionFunction
7 | {
8 | private readonly Expression expression;
9 |
10 | public ExpressionFunction(Expression expression)
11 | {
12 | this.expression = expression;
13 | }
14 |
15 | internal Delegate EvaluationFunction => (Func) Evaluate;
16 |
17 | private TResult Evaluate()
18 | {
19 | return (TResult)EvaluationScope.Empty.TryEvaluate(expression);
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/Mindbox.Expressions.Tests/AssertException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.TestTools.UnitTesting;
3 |
4 | namespace Mindbox.Expressions.Tests
5 | {
6 | public static class AssertException
7 | {
8 | public static void Throws(Action action, Action assertion)
9 | where TException : Exception
10 | {
11 | try
12 | {
13 | action();
14 | }
15 | catch (TException e)
16 | {
17 | assertion(e);
18 | return;
19 | }
20 |
21 | Assert.Fail($"Expected exception of type {typeof(TException)}, but is has never occured");
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/.github/workflows/pull-request.yml:
--------------------------------------------------------------------------------
1 | name: Pull Request
2 |
3 | on: pull_request
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - name: Checkout
10 | uses: actions/checkout@v1
11 |
12 | - name: Setup .NET 6
13 | uses: actions/setup-dotnet@v1
14 | with:
15 | dotnet-version: 6.0.x
16 |
17 | - name: Install dependencies
18 | run: dotnet restore
19 |
20 | - name: Build
21 | run: dotnet build ./Mindbox.Expressions.sln --configuration Release --no-restore
22 |
23 | - name: Test
24 | run: dotnet test --no-restore
25 |
--------------------------------------------------------------------------------
/Mindbox.Expressions/Mindbox.Expressions.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | Mindbox
6 | 3.3.1
7 | Mindbox.Expressions
8 | Allows to include lambda expressions into each other in c# and Visual Basic. Also allows to avoid using string constants in reflection thus enabling easy refactoring.
9 | Mindbox 2018
10 | Mindbox
11 | false
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Mindbox.Expressions/Evaluators/Caching/ClosureCapturedValuesVisitor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq.Expressions;
3 |
4 | namespace Mindbox.Expressions
5 | {
6 | internal abstract class ClosureCapturedValuesVisitor : ExpressionVisitor
7 | {
8 | protected ClosureCapturedValuesVisitor()
9 | {
10 |
11 | }
12 |
13 | protected sealed override Expression VisitConstant(ConstantExpression node)
14 | {
15 | if (node == null)
16 | throw new ArgumentNullException(nameof(node));
17 |
18 | if (node.Value == null)
19 | return base.VisitConstant(node);
20 |
21 | var replacedQuery = TryProcessClosure(node);
22 | if (replacedQuery != null)
23 | return replacedQuery;
24 |
25 | return base.VisitConstant(node);
26 | }
27 |
28 | protected abstract Expression TryProcessClosure(ConstantExpression node);
29 | }
30 | }
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Main Build
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v1
14 |
15 | - name: Setup .NET 6
16 | uses: actions/setup-dotnet@v1
17 | with:
18 | dotnet-version: 6.0.x
19 |
20 | - name: Install dependencies
21 | run: dotnet restore
22 |
23 | - name: Build
24 | run: dotnet build ./Mindbox.Expressions.sln --configuration Release --no-restore
25 |
26 | - name: Test
27 | run: dotnet test --no-restore
28 |
29 | - name: Pack
30 | run: dotnet pack ./Mindbox.Expressions.sln -c Release
31 |
32 | - name: Publish
33 | run: dotnet nuget push **/*.nupkg -k ${{secrets.MINDBOX_NUGET_AUTH_TOKEN}} -s https://api.nuget.org/v3/index.json
34 |
--------------------------------------------------------------------------------
/Mindbox.Expressions.Tests/Mindbox.Expressions.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net6.0
4 | Mindbox
5 | Mindbox.Expressions.Tests
6 | Copyright © Mindbox 2014
7 | Mindbox.Expressions.Tests
8 | Mindbox.Expressions.Tests
9 | latest
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Mindbox.Expressions/Evaluators/Caching/ClosureCapturedValuesProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq.Expressions;
4 |
5 | namespace Mindbox.Expressions
6 | {
7 | internal class ClosureCapturedValuesProvider : ClosureCapturedValuesVisitor
8 | {
9 | public static object[] GetCapturedValues(Expression expression)
10 | {
11 | var visitor = new ClosureCapturedValuesProvider();
12 | visitor.Visit(expression);
13 |
14 | return visitor.capturedValues.ToArray();
15 | }
16 |
17 | private ClosureCapturedValuesProvider()
18 | {
19 |
20 | }
21 |
22 | private readonly List