首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用CSharpCodeProvider允许用户创建函数

使用CSharpCodeProvider允许用户创建函数
EN

Stack Overflow用户
提问于 2013-02-06 13:25:51
回答 2查看 1.2K关注 0票数 1

我有一个现有的asp.net (c#)应用程序。我需要为用户提供一种创建灵活规则的方法,以计算给定雇用日期和注册日期的生效日期。

可能使用的一些规则实例:

  1. 雇用日期或入学日期的较晚日期
  2. HireDate + 90天
  3. 注册日期后一个月的第一个月
  4. 如果报名日期在当月15日之前,则生效日期为下一个月的第一天。如果是15号或以后,那是那个月的第一天。

我从一些偏移字段(日偏移量、月偏移量等)开始,但是当我遇到新的需求时,我开始意识到当前的方法不够灵活。

我想要做的是允许最终用户定义一个函数,该函数返回给定的两个参数(hiredate、注册日期)的日期,并将该函数存储在数据库中。当我需要计算有效值时,我会从数据库中取出这个函数,执行它,传递参数以获得我的有效值。

我的初步反应是寻找一个DSL,它将允许我定义日期操作函数并将其集成到我的解决方案中。然而,我对适当DSL的搜索没有发现任何结果。

现在,我想知道CSharpCodeProvider是否可以作为解决方案的组件工作。如果我从数据库中提取一个字符串,并通过CsharpCodeProvider编译它,我是否可以强制执行生成的代码与一个函数签名相匹配(接受2个日期时间参数,并返回一个数据)?

是否有办法确保该功能不产生任何副作用?例如,没有I/O,没有读取或会话、缓存或应用程序。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-06 13:39:03

请看我最近的回答:解析"DateTime.Now"?

本质上,您可以很容易地利用现有的库(如逃亡 )来解析表达式并为这些规则发出IL。如果您查看这些示例,可以看到如何为用户表达式设置变量以利用这些变量。例如,您可以定义一个由一些输入变量(如HireDateEnrollmentDate)组成的“规则”,以及返回日期的用户表达式/谓词。如果像我在链接答案中那样公开DateTime成员,那么用户也可以利用这些成员。

作为一个快速的例子,没有测试,但应该给你一个想法。

您可以设置一些自定义函数来帮助您,比如获得一个月的第一天:

代码语言:javascript
复制
public static class CustomFunctions
{
    public static DateTime GetFirstDayOfMonth(DateTime date)
    {
        return new DateTime(date.Year, date.Month, 1);
    }
}

基本的逃离设置(您必须根据需要自定义/调整)

代码语言:javascript
复制
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();

那么,您的规则可能看起来是:

代码语言:javascript
复制
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)))"; 
票数 2
EN

Stack Overflow用户

发布于 2013-05-27 11:13:57

下面的链接就是你想要的。本质上,它是一个可插件的DSL,它允许定义无限的日期计划和集合,然后传递给函数、交叉的、统一的等等。

http://code.google.com/p/drules/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14730219

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档