Я хочу сохранить выражение в базе данных, чтобы поддерживать механизм правил. Выражения в форме этого примера:
Expression<Func<MyTerm, bool>> expression = t => t.MyProperty == SomeValue;
Проблема, с которой я сталкиваюсь, заключается в том, что мне нужно создать MyTerm во время выполнения. Чтобы по-прежнему иметь возможность использовать MyTerm в качестве параметра для лямбда-выражения, я реализовал решение с ExpandoObject, например так:
public class MyTerm
{
ExpandoObject ParameterSet;
public void AddParameter(string name, object value)
{
IDictionary<string, object> dictionary = ParameterSet as IDictionary<string, object>;
if (dictionary.ContainsKey(name))
{
dictionary[name] = value;
}
else
{
dictionary.Add(name, value);
}
}
public string GetString(string name)
{
IDictionary<string, object> dictionary = ParameterSet as IDictionary<string, object>;
if (dictionary.ContainsKey(name))
{
return (string)dictionary[name];
}
throw new KeyNotFoundException("Term does not contain parameter {name}.");
}
Дело в том, что я получаю преимущество от возможности добавления параметровво время выполнения MyTerm, но я должен указать тип возвращаемого значения для каждого получателя, вместо возможности использовать приведенный выше синтаксис:
t.MyProperty
Есть ли способ использовать динамические объекты в качестве ввода для лямбда-выражений илиЕсть ли способы написать метод расширения для таких классов, чтобы вернуть объект, а не определенный тип? Я могу скомпилировать выражения следующим образом:
public static Func<MyTerm, bool> Compile(string body)
{
ParameterExpression term = Expression.Parameter(typeof(MyTerm), typeof(MyTerm).Name);
LambdaExpression exp = DynamicExpressionParser.ParseLambda(new[] { term }, typeof(bool), body);
return (Func<DynamicTerm, bool>)exp.Compile();
}
static void Main(string[] args)
{
MyTerm term = new MyTerm();
term.AddParameter("SomeParameter", "SomeValue");
Func<MyTerm, bool> IsGreaterThanSomeParameter = Compile("MyTerm.GetString(\"SomeParameter\")== SomeValue);
bool result = IsGreaterThanSomeParameter(term);
Console.WriteLine(result);
Console.ReadLine();
}
Я хочу хранить лямбда-выражения, которые не зависят от конкретной реализации, поэтому, если другой сервис пытается скомпилировать эти выражения обратно в функцию, синтаксис должен бытьможно использовать из коробки. Без каких-либо рабочих добытчиков. Заранее спасибо.