У меня есть приложение, где для каждого объекта пользователь может указать свои собственные измерительные точки. Значения этих измерений затем будут использоваться для классификации объекта как службы i-A, требуется B-обслуживание в течение X дней, C - нет необходимости в обслуживании ATM
Однако эти объекты могут быть почти любыми, и мы не можем жестко определить, как измеренные значения должны быть объединены с классификацией, мы должны оставить это для пользователя.
Есть ли у вас какие-либо предложения о том, как мы можем предоставить пользователю возможность вводить его собственные формулы? Это не должно быть идиот-доказательством, у нас не так много клиентов, поэтому мы можем помочь им, пока они могут объяснить это нам.
Вы можете предоставить пользователям список переменных, которые действительны для использования, и позволить им придумывать свои собственные выражения. Затем вы передадите все выражения, имена переменных и значения в Flee, и он разрешит все выражения для значения или true/false.
Я написал проект с открытым исходным кодом Dynamic Expresso, который может преобразовывать текстовое выражение, написанное с использованием синтаксиса С#, в делегаты (или дерево выражений), Выражения анализируются и преобразуются в Деревья выражений без использования компиляции или отражения.
Вы можете написать что-то вроде:
var interpreter = new Interpreter();
var result = interpreter.Eval("8 / 2 + 2");
или
var interpreter = new Interpreter()
.SetVariable("service", new ServiceExample());
string expression = "x > 4 ? service.SomeMethod() : service.AnotherMethod()";
Lambda parsedExpression = interpreter.Parse(expression,
new Parameter("x", typeof(int)));
parsedExpression.Invoke(5);
Моя работа основана на статье Скотта Гуа http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx.
Ваша ситуация - идеальный вариант для языка, специфичного для домена. DSL позволит вам указать допустимую грамматику для вашего "языка формул", а затем предоставить обратную связь пользователю, а также рассчитать результат.
Antlr - очень хороший инструмент для этого. Это генератор парсера/лексара. В основном вы указываете грамматику в собственном описании DSL Antlr, и она генерирует надежные лексеры и синтаксические анализаторы для вас на выбранном вами языке.
Например, если ваш язык допускает простые вычисления, так это будет указано в языке antlr (из antlr wiki):
grammar SimpleCalc;
options {
language=CSharp2;
}
tokens {
PLUS = '+' ;
MINUS = '-' ;
MULT = '*' ;
DIV = '/' ;
}
@members {
public static void Main(string[] args) {
SimpleCalcLexer lex = new SimpleCalcLexer(new ANTLRFileStream(args[0]));
CommonTokenStream tokens = new CommonTokenStream(lex);
SimpleCalcParser parser = new SimpleCalcParser(tokens);
try {
parser.expr();
} catch (RecognitionException e) {
Console.Error.WriteLine(e.StackTrace);
}
}
}
/*------------------------------------------------------------------
* PARSER RULES
*------------------------------------------------------------------*/
expr : term ( ( PLUS | MINUS ) term )* ;
term : factor ( ( MULT | DIV ) factor )* ;
factor : NUMBER ;
/*------------------------------------------------------------------
* LEXER RULES
*------------------------------------------------------------------*/
NUMBER : (DIGIT)+ ;
WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; } ;
fragment DIGIT : '0'..'9' ;
Вы можете узнать больше о DSL вообще здесь.
SpreadsheetGear для .NET может быть хорошим выбором. SpreadsheetGear принимает и вычисляет формулы на языке, который большинство пользователей уже знают - Excel. SpreadsheetGear включает в себя элемент управления электронной таблицей Windows Forms, или вы можете использовать его в качестве библиотеки, если вы делаете ASP.NET или веб-службу.
Вы можете увидеть простые примеры расчета ASP.NET здесь или загрузить бесплатную пробную версию здесь, если вы хотите попробовать элемент управления WinForms.
Отказ от ответственности: у меня есть SpreadsheetGear LLC
Вы упомянули, что объекты могут быть "почти любыми". Может ли мера также быть почти чем угодно? Предположительно, измерения будут ограничены определенными свойствами объекта, о котором идет речь, и в этом случае вы, вероятно, можете открыть редактор, похожий на мастера, который позволит пользователю выполнять вычисления на основе свойств объектов, обнаруженных с помощью отражения. Одна вещь, которую вы делаете для вас путем ограничения проблемы, состоит в том, что вы, похоже, применяете 3 конечных точки для измерения вместо 1-го состояния.
Последнее предложение, я думаю, для достаточной гибкости вам понадобится независимая модель объекта измерения, которая привязывается к объектам, которые вы хотите измерить.
Насколько важно для вас обеспечить эксклюзивность измерений? Защита пользователя от определения перекрывающихся состояний, возможно, будет самой сложной частью этого, поскольку из вашего описания казалось бы, что совершенно разные измерения действительны для присоединения к различным состояниям.
Кроме того, знаете ли вы, как вы будете опросить объекты для вычисления измерений, чтобы определить состояние объектов?
Извините, что говоришь так вообще, но на самом деле в этот момент ваш вопрос довольно общий. Удачи.
Вы должны использовать выражения .NET 3.5 в System.Linq.Expressions. Скотт Гу предоставил API динамического выражения, который позволяет вам оценивать строки, чтобы превратить их в деревья выражений, которые затем могут быть оценены кодом либо для проверки содержимого выражения, либо скомпилированы для выполнения.
Может ли пользователь использовать свои знания об объекте и просто решить, какую категорию включить, когда он войдет в систему? Угадайте, нам нужна дополнительная информация, но если пользователь может определить, какие измерения определяют, какую категорию, не могли они просто выбрать категорию?