How to implement a rule engine?

后端 未结 10 1965
借酒劲吻你
借酒劲吻你 2020-11-27 23:58

I have a db table that stores the following:

RuleID  objectProperty ComparisonOperator  TargetValue
1       age            \'greater_than\'             15
2          


        
10条回答
  •  刺人心
    刺人心 (楼主)
    2020-11-28 00:44

    Here is some code that compiles as is and does the job. Basically use two dictionaries, one containing a mapping from operator names to boolean functions, and another containing a map from the property names of the User type to PropertyInfos used to invoke the property getter (if public). You pass the User instance, and the three values from your table to the static Apply method.

    class User
    {
        public int Age { get; set; }
        public string UserName { get; set; }
    }
    
    class Operator
    {
        private static Dictionary> s_operators;
        private static Dictionary s_properties;
        static Operator()
        {
            s_operators = new Dictionary>();
            s_operators["greater_than"] = new Func(s_opGreaterThan);
            s_operators["equal"] = new Func(s_opEqual);
    
            s_properties = typeof(User).GetProperties().ToDictionary(propInfo => propInfo.Name);
        }
    
        public static bool Apply(User user, string op, string prop, object target)
        {
            return s_operators[op](GetPropValue(user, prop), target);
        }
    
        private static object GetPropValue(User user, string prop)
        {
            PropertyInfo propInfo = s_properties[prop];
            return propInfo.GetGetMethod(false).Invoke(user, null);
        }
    
        #region Operators
    
        static bool s_opGreaterThan(object o1, object o2)
        {
            if (o1 == null || o2 == null || o1.GetType() != o2.GetType() || !(o1 is IComparable))
                return false;
            return (o1 as IComparable).CompareTo(o2) > 0;
        }
    
        static bool s_opEqual(object o1, object o2)
        {
            return o1 == o2;
        }
    
        //etc.
    
        #endregion
    
        public static void Main(string[] args)
        {
            User user = new User() { Age = 16, UserName = "John" };
            Console.WriteLine(Operator.Apply(user, "greater_than", "Age", 15));
            Console.WriteLine(Operator.Apply(user, "greater_than", "Age", 17));
            Console.WriteLine(Operator.Apply(user, "equal", "UserName", "John"));
            Console.WriteLine(Operator.Apply(user, "equal", "UserName", "Bob"));
        }
    }
    

提交回复
热议问题