2008-10-16 20 views
65

¿Alguien sabe de una buena biblioteca de reglas de biblioteca .NET (idealmente de código abierto)? Necesito algo que pueda hacer expresiones lógicas anidadas, por ejemplo, (A y B) Y (B o C o D). Necesito hacer comparaciones de las propiedades del objeto, por ejemplo, A.P1 y B.P1. (Idealmente, podría comparar cualquier propiedad - A.P1 Y B.P2).Buscando reglas simples: biblioteca de motores en .NET

Debe almacenar las reglas en una base de datos (tengo mucha lógica configurable simple). Y debe tener una API de creación/administración de reglas. La herramienta de gestión debería inspeccionar las instancias para determinar qué propiedades están disponibles y qué restricciones existen.

Gracias!


Oh, una cosa más. Como motor de reglas, necesito incluir el concepto de Acciones (Comandos). Estos son los que se ejecuta cuando la expresión devuelve:

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

así que no veo una regla como algo parecido a:

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

Respuesta

5

La solución oficial de MS para esto es Windows Workflow. Aunque no lo llamaría "simple", cumple con todas sus especificaciones (lo que requeriría un amplio marco de trabajo para cumplir, de todos modos).

+0

Existe un inconveniente para el actual motor de reglas WF ... usa un subconjunto muy pequeño de expresiones codificadas, pero en realidad realiza un análisis de cadenas para generar el código subyacente, no las clases CodeDom. –

+0

Inicialmente estaba usando Drools 3.0. Pero no es compatible con .Net Framework 4.5. Entonces, ¿puedo usar esto como un sustituto de Drools? –

+0

@ShyamDixit: Lo siento, no tengo idea, pero elegiría cualquier cosa en desarrollo actual a través de WF3. Esta respuesta tiene casi seis años. No tome decisiones leyendo artículos/preguntas/respuestas antiguas. – Will

7

Bueno, como la expresión lógica es solo un subconjunto de la expresión matemática, es posible que desee probar NCalc - Mathematical Expressions Evaluator for .NET en CodePlex.

+0

Oye, eso es bastante bonito. Aunque a partir de los ejemplos, creo que podría haber una manera más elegante de evaluar las expresiones delegadas. Este podría ser el punto de extensión para insertar una reflexión sobre la expresión operandos. – Kurtz

7

Ninguna de las .NET rules-engine de fuente abierta tiene soporte para almacenar reglas en la base de datos. Los únicos que almacenaron las reglas en una base de datos son comerciales. He creado algunas interfaces de usuario para motores de reglas personalizadas que se ejecutan en la base de datos, pero esto puede ser no trivial para implementar. Esa suele ser la razón principal por la que no verá esa función de forma gratuita.

Por lo que yo sé, ninguno de ellos cumple con todos los criterios, pero aquí hay una lista de los que conozco de:

más simple es SRE
http://sourceforge.net/projects/sdsre/

Uno con el artículo IU de administración es NxBRE
http://www.agilepartner.net/oss/nxbre/

Drools.NET utiliza JBoss Rules
http://droolsdotnet.codehaus.org/

Personalmente no he usado ninguno de ellos, porque todos los proyectos con los que trabajé nunca quisieron usar algo construido internamente. La mayoría de los negocios piensan que esto es bastante fácil de hacer, pero terminan perdiendo demasiado tiempo codificándolo e implementándolo. Esta es una de esas áreas que gobierna el Síndrome No Inventado Aquí (NIH).

+2

Drools.NET no es una buena idea, depende de una implementación de JVM en .Net aún en versión beta, lo probé y realmente no está listo para producción en mi humilde opinión. – pmlarocque

+1

¿Alguien ha usado SRE aquí? ¿Cuál fue la experiencia? – Kurtz

17

Aquí hay una clase que he usado en el pasado. Evalúa cadenas al igual que eval() en Javascript.

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

Todo lo que necesita hacer es construir una cadena a evaluarse a partir de los objetos de negocio y esto se hará cargo de toda la lógica anidada complicada etc.

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 
    }  
} 
+3

+1. ¡Impresionante! – David

+2

Probé tu código en mi aplicación web. Desafortunadamente, la compilación dinámica no funciona con aplicaciones web debido a los permisos de la carpeta asp temp. –

0

Dependiendo de lo que está tratando de hacer uso de expresiones Lambda (y árboles de expresión) puede funcionar para este concepto.Esencialmente, usted proporciona una expresión como una cadena que luego se compila sobre la marcha en un árbol de expresiones/expresiones lambda, que luego puede ejecutar (evaluar). No es fácil de entender al principio, pero una vez que lo haces es extremadamente potente y bastante fácil de configurar.

+0

Bien, entiendo el uso de expresiones Lambda y las usaría si estuviera construyendo esto desde cero. Pero, espero que las agallas de esta biblioteca ya existan o puedan ser combinadas. – Kurtz

+0

No es que yo sepa de ... hay varias bibliotecas de tipos de motor de reglas disponibles, pero ninguna de ellas es particularmente simple y/o eficiente y ninguna hace uso de expresiones lambda. –

46

Estoy de acuerdo con la voluntad de que utilice algo de la familia de motores de flujo de trabajo, aunque no flujo de trabajo. Examine System.Workflow.Activities.Rules Namespace un poco - es compatible con .Net 3 y está integrado en .Net3.5. Usted tiene todo en la mano de forma gratuita para usar como usted ha mencionado:

  • RuleCondition de condiciones, RuleAction para las acciones

  • formato normalizado para describir metacódigo (CodeDom - CodeExpressions)

  • que pueda plugin cualquier tipo de complejidad en eso (a decir verdad, excepto Linq y lambdas y por lo tanto, extensión métodos de algún tipo) a través de TypeProviders

  • hay un editor incorporado para la regla edición con IntelliSense

  • como la regla es serializable que puede ser fácilmente persistió

  • si nos referimos a utilizar las reglas sobre un sistema de base de datos entonces a través de typeprovider se puede implementar también

Para un aperitivo: Using rules outside of a workflow

Obs .: lo estamos utilizando extensivamente y hay mucho más en ese espacio de nombres de lo que nunca imagine -> un lenguaje algoritmo de meta completa

Y lo más importante: es fácil de usar - muy

+1

gran publicación, eso es lo que usamos en el pasado y lo encontramos bastante poderoso para aprovechar la parte del motor de reglas fuera de todo el marco de trabajo de Windows. –

0

Quizás desproteger SmartRules. No es gratis, pero la interfaz parece bastante simple.

Solo sé al respecto porque he utilizado la utilidad codegen SmartCode desde allí anteriormente.

Aquí es una regla de ejemplo de la página web:

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 
+0

Difunto ahora. Prueba en otro lado. – Firestrand

0

No es gratis, como no se puede desenredar fácilmente de su filiación BizTalk, pero los componentes del motor de reglas de negocios de BizTalk son una entidad separada de el motor principal de BizTalk, y comprende un motor de reglas muy poderoso que incluye una GUI basada en reglas/políticas. Si hubiera una versión gratuita de esto, se ajustaría a sus requisitos (comprar BizTalk solo para el BRE realmente no funcionaría comercialmente).

3

Windows Workflow Foundation le ofrece un motor de inferencia de encadenamiento directo. Y puede usarlo sin la parte del flujo de trabajo. Crear y editar reglas está bien para los desarrolladores.

Si desea que los no programadores editen y mantengan las reglas, puede probar el Rule Manager.

Rule Manager generará una solución visual de estudio visual para usted. Eso debería comenzar bastante rápido. Simplemente haga clic en Archivo \ Exportar y seleccione el formato WFRules.

+0

Este es un serilizador mejorado para el motor de reglas de WWF: https://github.com/chriseyre2000/perfectstorm/tree/master – Chriseyre2000

2

Puede echar un vistazo a nuestro producto, así en http://www.FlexRule.com

FlexRule es un marco motor de reglas de negocio con el apoyo de tres motores; Motor de procedimiento, motor de inferencia y motor RuleFlow. Su motor de inferencia es una inferencia de encadenamiento hacia delante que utiliza una implementación mejorada del algoritmo Rete.

Cuestiones relacionadas