The Loopo Rules Engine - Part 2
In order to create a Rules Engine to fit our needs, some planning was needed. The first thing to do was to read up on rules engines in general - Wikipedia provided some answers. Their description of Forward Chaining sounded like what we wanted. It’s basically just a list of IF condition then action END IF statements that gets executed in sequence, although we opted to be able to run each rule as a IF condition then actions else otheractions END IF.
We also needed to figure out how to hook this engine into our current LFO Framework without causing too much disruption, ideally it should be able to co-exist with the old way of dealing with business rules.
The LFO Framework data model works with a concept of a Page (either a web page or a windows form), which can contain one or more Panels or Lists, Each Panel can hold a Record of a special Type, a Record could be seen to correspond to a database row, although in reality we use stored procedures view/add/edit/delete functionality. Type here means what fields the record contains and what data types they are. Lists are a special type of Panel that can hold multiple records of a special type.
All these records and fields can trigger and receive events inbetween each other and this need must be full filled by the rules engine.
The old way of handling consisted of defining an object that implemented the IRecordControl, IListControl or the IListRecordControl interface and then handed this object over to the Framework, The Framework would then call the corresponding method on that object for each event that occurred within it, e.g. before a field update it calls RecordPreFieldSet, then after the field update it calls RecordPostFieldSet, after adding a row in a list it would call ListRecordRowPostCreation and so on.
All these methods or event handlers had to be defined in your interface otherwise the application wouldn’t compile, so you were left with lots of empty stubs of event handlers in the code, which didn’t look very pretty. However as we had all the right events already being triggered, it was just a case of building an EventManager that could be set by default to be the recipient of all these events.
While that’s all well and good, the EventManager needs to be able to send the events on to something, that would be our Rules Engine then.
The RulesEngine is responsible for parsing all rules form our XML file on startup, then it registers itself with the EventManager, telling the EventManager that it’s willing to receive events from the framework. When an event comes in, the Rules Engine takes the event and the object that caused it and checks if any rules exists for this combination. If so it goes on executing each rule in sequence until they are all called or if the executed rule called a BreakRulesChainAction.
As mentioned, each rule has a set of actions, which which runs in case of success and another optional set of actions which runs in case of failure. Each action is based upon an abstract base class which have an empty method called Execute(), which each of the ’specialised’ action classes has to implement. The implemented actions so far includes actions for messaging user and updating fields and grids - which, thanks to our LFO Framework automatically work for both Windows applications and web applications.
One thing we needed to take into account was that we might want to update other records and grids than the one that caused the event, i.e. if we add a row to the receipts grid in our fictitious application, we want the order action grid to have a “Order Paid” row added. We hence saw the need to build up an object pool of all open data records and all grids belonging these records, this pool is sent along with the rule when it’s executed so it can access all neccesary data.
Of course, our rules engine is a piece of code that just has to work, thus it must be thoroughly tested, which I will talk more about in the next part.
Part 1 Part 3 (to be continued)
Posted by Fredrik on November 22, 2007 in Uncategorized


Loopo Blog » The Loopo Rules Engine - Part 1 said,
February 15, 2008 @ 9:40 am
[...] continued: Part 2 [...]