Database driven rule engine

Aug 15, 2013 at 7:19 PM
Hi,

I like this project very much and it is in-line with my requirements. Thanks a ton for this.

I need to give an interface for the user to to create his own rules on a data set. This is primarily for validating data imported from flat files.

My idea is when the user defines his rules i need to store them in a table in database and generate all these validation on the fly. Not sure how can i do that. Also is it required to do this every time or do I have an option where i can generate all rule as a class programaticaly and use that every time and re-create the class when ever user changes roles again.

Any suggestion is highly appreciated.

Thanks
Coordinator
Aug 16, 2013 at 5:24 AM
Hi,

Thanks for liking this project...

Ok first, after building a rules engine (i.e. Adding rules to it). You should re-use the Engine's instance instead of re-building it every time you want to Validate something. This will give you some performance gains as there are some optimizations that occur when you first Validate an object. So make it available through ServiceLocation (e.g. Singleton in Unity) or simply in a static variable (watch for locking when adding rules at runtime).

Adding rules from a Database:

The Engine works by having 'Invokers' added to it's InvokerRegistry. Most of the Invokers added to the InvokerRegistry will be RuleInvokers see RuleInvoker<T, R> Where T is the class being validated, and R the property type. E.g. Validating 'Name' on a object of type 'Person' using a RegexRule you would need to add a RuleInvoker of type RuleInvoker<Person, String> to the InvokerRegistry

e.g.
...
var engine = new Engine();
engine.InvokerRegistry.RegisterInvoker(
            new RuleInvoker<Person, String>(new RegexRule(new Regex("..")),
            new DefaultValueResolver<Person, String>(p => p.Name),
            DatabaseRuleHelper.Expression<Person, String>(p => p.Name),
            new DefaultCulpritResolver(DatabaseRuleHelper.Expression<Person, String>(p => p.Name))
);
...

public static class DatabaseRuleHelper
{
   public static Expression<Func<T, R>> Expression<T, R>(Expression<Func<T, R>> expression)
   {
        return expression;
    }
}
For your database rules, you will have to be clever with the Type you want to validate, and be able to create a LambdaExpression from a database field e.g. Your table could have fields:
Type, Property, Rule, Arg1, Arg2, Arg3, Arg4, Arg5

Then have a loop over the table to add Invokers to the RuleEngine. There's a bit of work involved of course... but let me know how you go.