Я использую VS 2015, C#, целевой фреймворк 4.6.1 для разработки способа выполнения действий правил, созданных конечными пользователями и сохраненных в базе данных. Идея состоит в том, чтобы позволить им вводить строку, представляющую команду, подобную следующей: CompareDatesReturnGreater(date1 => PushDate(//HEADER/ProcessDate, 7, Sat: Sun, //START/Branch), date2 => SetToToday())
Я могу легко получить имя метода CompareDatesReturnGreater, проанализировав входные данные, но если есть вложенные вызовы, становится сложнее разобрать все вызовы метода с правильными параметрами - не невозможно, но сложнее.
Я обнаружил, что работает следующий метод - выполняет вложенные вызовы и т. д. c. - но я не могу понять, как получить из строки, которая представляет эти выражения, фактическое выражение.
public string ExternalCall()
{
string result = string.Empty;
string input = "CompareDatesReturnGreaterFromFunc(date1 => PushDate(//HEADER/ProcessDate, 7, Sat: Sun, //START/Branch), date2 => SetToToday())";
List<string> commands = SplitCommand(input);
MethodInfo mi = this.GetType().GetMethod(commands[0], BindingFlags.Instance | BindingFlags.NonPublic);
List<object> miParams = new List<object>();
Expression<Func<string, string>> f1 = date1 => PushDate("//HEADER/ProcessDate", "7", "Sat: Sun", "//START/Branch");
miParams.Add(f1);
Expression<Func<string, string>> f2 = date1 => SetToToday();
miParams.Add(f2);
result = (string)mi.Invoke(this, miParams.ToArray());
return result;
}
Вызванный метод принимает выражения и использует их для создания MethodCallExpressions. Они используются для вызова окончательного метода для генерации результата.
public string CompareDatesReturnGreaterFromFunc(Expression<Func<string, string>> func1, Expression<Func<string, string>> func2)
{
string result = string.Empty;
MethodCallExpression operation1 = (MethodCallExpression)func1.Body;
string result1 = (string)Expression.Lambda(operation1).Compile().DynamicInvoke();
MethodCallExpression operation2 = (MethodCallExpression)func2.Body;
string result2 = (string)Expression.Lambda(operation2).Compile().DynamicInvoke();
result = CompareDates(result1, result2, true);
return result;
}
Я нашел предложения по использованию пакета Roslyn, но не смог их правильно установить в VS 2015 для целевой платформы.
Или есть лучший способ выполнить это sh без использования выражений?