The best way to identify business rules is with xml. To take full advantage of this notation, you must start by defining the structure of the data model with the rule engine, that is, answer these questions.
- What are the rules?
- Can the rules be classified?
- Do the rules contain common properties (attributes), such as valid values, format, etc.?
Once this is done, create dummy xml rules, and then output the xml schema based on that xml. The xsd.exe tool will help you in creating the schema. It's easier to create a schema if you can use tools like Altova XmlSpy .
Regarding the answers to your specific questions,
- We cannot use Intellisense, and if we have an error in the XML file, it is very difficult to find.
When you have a schema in place, Visual Studio provides extensive support for creating xml (including intellisense and validation).
- We have to write our own XML parsers
Not required XmlSerializer Class provides serialization / deserialization logic, i.e. convert xml rules to rule data model and vice versa.
- Because this method requires a lot of castings, it is very slow
Well, this is partly a valid point compared to hard-coded rules (rules that are built into your assembly as classes), but the flexibility of this approach far exceeds any performance flaws. You do not need to rebuild the decision in case of a change in the rules. In most cases, the impact of performance is minimal.
Unless you have strict performance criteria, the xml approach is the preferred way to implement the rule engine. Remember that the more loosely coupled your architecture, the greater the flexibility at runtime, but there is a negative impact on performance.
Rule example
<RulesEngine> <Rules> <Rule Id="Rule1"> <Function> <Equals> <Property name="Property1" classId="MyClassId"/> <Sum> <Property name="Property2" classId="MyClassId"/> <Constant type="UInt16" value="1"/> </Sum> </Equals> </Function> </Rule> </Rules> <Classes> <Class name="MyNamespace.MyClass" Id="MyClassId"> <Property name="Property1" type="UInt16"/> <Property name="Property2" type="UInt16"/> </Class> </Classes> </RulesEngine>
The rule engine should interpret this rule and output the value accordingly.