在这里查看我最近的答案:解析“DateTime.Now”?
从本质上讲,您可以轻松地利用现有的库(如FLEE)来解析表达式并为这些规则发出 IL。如果您查看示例,您可以了解如何设置变量以供用户表达式利用。例如,您可以定义一个“规则”,它由一些输入变量(如HireDate
or EnrollmentDate
)和一个返回日期的用户表达式/谓词组成。如果您DateTime
像我在链接的答案中那样公开成员,那么用户也可以利用这些成员。
就像一个简单的例子,未经测试,但应该给你一个想法。
您可以设置一些自定义函数来提供帮助,例如获取一个月的第一天:
public static class CustomFunctions
{
public static DateTime GetFirstDayOfMonth(DateTime date)
{
return new DateTime(date.Year, date.Month, 1);
}
}
基本的 FLEE 设置(您必须根据需要进行自定义/调整)
ExpressionContext context = new ExpressionContext();
//Tell FLEE to expect a DateTime result; if the expression evaluates otherwise,
//throws an ExpressionCompileException when compiling the expression
context.Options.ResultType = typeof(DateTime);
//Instruct FLEE to expose the `DateTime` static members and have
//them accessible via "DateTime".
//This mimics the same exact C# syntax to access `DateTime.Now`
context.Imports.AddType(typeof(DateTime), "DateTime");
context.Imports.AddType(typeof(CustomFunctions));
//Expose your key variables like HireDate and EnrollmentDate
context.Variables["HireDate"] = GetHireDate(); //DateTime I suppose
context.Variables["EnrollmentDate"] = GetEnrollmentDate(); //DateTime I suppose
//Parse the expression, naturally the string would come from your data source
IGenericExpression<DateTime> expression = context.CompileGeneric<DateTime>(GetYourRule(), context);
DateTime date = expression.Evaluate();
那么您的规则可能如下所示:
string rule1 = "if(HireDate > EnrollmentDate, HireDate, EnrollmentDate)";
string rule2 = "HireDate.AddDays(90)";
string rule3 = "GetFirstDayOfMonth(EnrollmentDate.AddMonths(1))";
string rule4 = "GetFirstDayOfMonth(EnrollmentDate.AddMonths(if(EnrollmentDate.Day < 15, 1, 2)))";