【问题标题】:Looking for simple rules-engine library in .NET [closed]在.NET中寻找简单的规则引擎库[关闭]
【发布时间】:2010-09-17 13:02:49
【问题描述】:

有谁知道一个好的 .NET 库规则库(最好是开源的)?我需要一些可以执行嵌套逻辑表达式的东西,例如 (A AND B) AND (B OR C OR D)。我需要比较对象属性,例如 A.P1 和 B.P1。 (理想情况下,我可以比较任何属性——A.P1 和 B.P2)。

它应该将规则存储在数据库中(我有很多简单的可配置逻辑)。它应该有一个规则创建/管理 API。管理工具必须检查实例以确定哪些属性可用以及存在哪些约束。

谢谢!


哦,还有一件事。作为规则引擎,我需要包含操作(命令)的概念。这些是表达式返回时执行的内容:

If (expression.Evaluation) { actions.Execute(); }

所以我认为一个规则是这样的:

class Rule
{
    Expression Exp;
    Actions[] Actions;
    Run() 
    { 
        if(Exp.Evaluate()) 
        { 
            foreach(action in Actions) 
            { 
                action.Execute(); 
            }
        } 
    }
}

【问题讨论】:

    标签: c# .net .net-core logic rule-engine


    【解决方案1】:

    同意我会说使用工作流引擎系列中的一些东西,尽管不是工作流。 稍微检查一下 System.Workflow.Activities.Rules 命名空间 - 它在 .Net 3 中受支持,并内置在 .Net3.5 中。就像您提到的那样,您可以免费使用所有东西:

    • RuleCondition 用于条件,RuleAction 用于操作

    • 用于描述的标准化格式 元代码(CodeDom - CodeExpressions)

    • 您可以插入任何类型的复杂性 进入那个(说实话,除了 Linq 和 lambdas 等扩展 某种方法)通过 类型提供者

    • 有一个内置的规则编辑器 使用智能感知编辑

    • 因为规则是可序列化的,它可以是 容易持久

    • 如果您打算使用规则而不是 数据库方案然后通过 typeprovider 也可以实现

    首先: Using rules outside of a workflow

    Ps.:我们正在广泛使用它,并且该命名空间中的内容比您想象的要多得多 -> 一种完整的元算法语言

    最重要的是:它易于使用 - 真的

    【讨论】:

    • 很棒的帖子,这是我们过去使用的,发现它非常强大,可以利用所有 Windows 工作流框架之外的规则引擎部分。
    【解决方案2】:

    这是我过去使用过的一个类。它像 eval() 在 Javascript 中一样评估字符串。

    String result = ExpressionEvaluator.EvaluateToString("(2+5) < 8");
    

    您需要做的就是从您的业务对象中构造一个要评估的字符串,这将处理所有复杂的嵌套逻辑等。

    using System;
    using System.CodeDom.Compiler;
    using System.Globalization;
    using System.Reflection;
    using Microsoft.JScript;
    
    namespace Common.Rule
    {
      internal static class ExpressionEvaluator
      {
        #region static members
        private static object _evaluator = GetEvaluator();
        private static Type _evaluatorType;
        private const string _evaluatorSourceCode =
            @"package Evaluator
                {
                   class Evaluator
                   {
                      public function Eval(expr : String) : String 
                      { 
                         return eval(expr); 
                      }
                   }
                }";
    
        #endregion
    
        #region static methods
        private static object GetEvaluator()
        {
          CompilerParameters parameters;
          parameters = new CompilerParameters();
          parameters.GenerateInMemory = true;
    
          JScriptCodeProvider jp = new JScriptCodeProvider();
          CompilerResults results = jp.CompileAssemblyFromSource(parameters, _evaluatorSourceCode);
    
          Assembly assembly = results.CompiledAssembly;
          _evaluatorType = assembly.GetType("Evaluator.Evaluator");
    
          return Activator.CreateInstance(_evaluatorType);
        }
    
        /// <summary>
        /// Executes the passed JScript Statement and returns the string representation of the result
        /// </summary>
        /// <param name="statement">A JScript statement to execute</param>
        /// <returns>The string representation of the result of evaluating the passed statement</returns>
        public static string EvaluateToString(string statement)
        {
          object o = EvaluateToObject(statement);
          return o.ToString();
        }
    
        /// <summary>
        /// Executes the passed JScript Statement and returns the result
        /// </summary>
        /// <param name="statement">A JScript statement to execute</param>
        /// <returns>The result of evaluating the passed statement</returns>
        public static object EvaluateToObject(string statement)
        {
          lock (_evaluator)
          {
            return _evaluatorType.InvokeMember(
                        "Eval",
                        BindingFlags.InvokeMethod,
                        null,
                        _evaluator,
                        new object[] { statement },
                        CultureInfo.CurrentCulture
                     );
          }
        }
        #endregion
      }    
    }
    

    【讨论】:

    • 我在我的网络应用程序上尝试了您的代码。不幸的是,由于对 asp temp 文件夹的权限,动态编译不适用于 Web 应用程序。
    【解决方案3】:

    开源的 .NET 规则引擎都不支持在数据库中存储规则。唯一将规则存储在数据库中的是商业的。我已经为在数据库之外运行的自定义规则引擎创建了一些 UI,但这可能并不容易实现。这通常是您不会免费看到该功能的主要原因。

    据我所知,它们都不符合您的所有标准,但以下是我所知道的列表:

    最简单的是 SRE
    http://sourceforge.net/projects/sdsre/

    具有规则管理 UI 的是 NxBRE
    http://www.agilepartner.net/oss/nxbre/

    Drools.NET 使用 JBOSS 规则
    http://droolsdotnet.codehaus.org/

    我个人没有使用过它们,因为我参与的所有项目都不想使用内部构建的东西。大多数企业认为这很容易做到,但最终浪费了太多时间编码和实现它。这是此处未发明综合症 (NIH) 规定的领域之一。

    【讨论】:

    • Drools.NET 不是一个好主意,依赖于 .Net 中的 JVM 实现仍处于测试阶段,尝试过,恕我直言,它真的不能用于生产。
    • 这里有人用过 SRE 吗?体验如何?
    【解决方案4】:

    好吧,由于逻辑表达式只是数学表达式的子集,您可能想在 CodePlex 上尝试NCalc - Mathematical Expressions Evaluator for .NET

    【讨论】:

    • 嘿,这实际上很整洁。尽管从示例中,我认为可以有一种更优雅的方式来评估委托表达式。这可能是在表达式操作数上插入一些反射的扩展点。
    【解决方案5】:

    官方的 MS 解决方案是 Windows Workflow。虽然我不会称它为“简单”,但它符合您的所有规范(无论如何,这需要一个广泛的框架来满足)。

    【讨论】:

    • 当前的 WF 规则引擎有一个缺点......它使用了非常小的 codedom 表达式子集,但实际上是通过字符串解析来生成底层代码 - 而不是 CodeDom 类。
    • 最初我使用的是 Drools 3.0。但它不支持 .Net Framework 4.5。那么我可以用它来代替 Drools 吗??
    • @ShyamDixit:抱歉,不知道,但我会选择当前开发中的任何内容,而不是 WF3。这个答案已经有将近六年的历史了。不要通过阅读古老的文章/问题/答案来做出决定。
    • 是否可以使用WF来解析数据?? @威尔
    • @ShyamDixit:我不会推荐它。
    【解决方案6】:

    我过去曾成功使用过这个http://www.codeproject.com/KB/recipes/Flee.aspx。试一试。

    【讨论】:

      【解决方案7】:

      Windows Workflow Foundation 确实为您提供了免费的前向链接推理引擎。您可以在没有工作流部分的情况下使用它。开发人员可以创建和编辑规则。

      如果您想让非程序员编辑和维护规则,您可以试试Rule Manager

      规则管理器将为您生成一个有效的 Visual Studio 解决方案。这应该让你很快开始。只需点击 File \ Export 并选择 WFRules 格式。

      【讨论】:

      【解决方案8】:

      您也可以通过http://www.FlexRule.com查看我们的产品

      FlexRule 是一个业务规则引擎框架,支持三个引擎;程序引擎、推理引擎和规则流引擎。它的推理引擎是使用 Rete 算法的增强实现的前向链接推理。

      【讨论】:

        【解决方案9】:

        我会看看 Windows 工作流。规则引擎和工作流程往往一开始很简单,然后逐渐变得复杂。像 Windows Workflow Foundation 这样的东西起步并不难,并且提供了增长空间。 Here is a post that shows it's not too difficult to get a simple workflow engine going.

        【讨论】:

          【解决方案10】:

          也许看看SmartRules。它不是免费的,但界面看起来很简单。

          只知道它,因为我以前使用过 SmartCode codegen 实用程序。

          这是来自网站的示例规则:

          BUSINESS RULES IN NATURAL LANGUAGE      
          
          Before
          If (Customer.Age > 50 && Customer.Status == Status.Active) {
          policy.SetDiscount(true, 10%);
          }
          
          After (with Smart Rules)
          If Customer is older than 50 and
          the Customer Status is Active Then
          Apply 10 % of Discount
          

          【讨论】:

          • 现已失效。换个地方试试。
          【解决方案11】:

          你可以使用 RuEn,一个由我创建的简单的基于开源属性的规则引擎:

          http://ruen.codeplex.com

          【讨论】:

            【解决方案12】:

            试试看 http://rulesengine.codeplex.com/

            这是一个适用于表达式树的 C# 开源规则引擎。

            【讨论】:

              【解决方案13】:

              看看 Logician:CodeProject 上的tutorial/overview

              项目:SourceForge 上的page/source

              【讨论】:

                【解决方案14】:

                根据您尝试使用 Lambda 表达式(和表达式树)执行的操作,此概念是否有效。本质上,您将表达式作为字符串提供,然后动态编译成 lambda 表达式/表达式树,然后您可以执行(评估)。一开始并不容易理解,但是一旦你理解它就会变得非常强大并且设置起来相当简单。

                【讨论】:

                • 对,我了解 Lambda 表达式的使用,如果我从头开始构建它,我会使用它们。但是,我希望这个库的内容已经存在或者可以拼凑起来。
                • 我不知道...有几个可用的规则引擎类型库,但没有一个特别简单和/或高效,也没有一个使用 lambda 表达式。
                【解决方案15】:

                它不是免费的,因为你不能轻易地将它从 BizTalk 的血统中解开,但是 BizTalk 的业务规则引擎组件是一个独立于核心 BizTalk 引擎本身的实体,并且包含一个非常强大的规则引擎,其中包含一个规则/ 基于策略的 GUI。如果有这样的免费版本,它将满足您的要求(仅为 BRE 购买 BizTalk 并不能真正实现商业化。)

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2011-05-18
                  • 2011-12-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-01-10
                  • 1970-01-01
                  相关资源
                  最近更新 更多