Exploring Microsoft’s Rules Engine

Photo by Campaign Creators on Unsplash

Whether you’re developing a customer facing service or an internal enterprise tool, introducing rules engine technologies can boost the range of configuration options dramatically. I’ve recently concluded an evaluation of Microsoft’s open source rules engine (see its GitHub repo here) on behalf of a client and overall my impression is positive.

Why Would You Use a Rules Engine?

Every customer facing product or system has some logic where the decisions are controlled as a result of business rules. Those rules could be as simple as a yes/no decision based on some information – is a customer resident in a particular country for example – or more complex such as does the customer have a a specific balance in their bank account for the last three months and also have a particular level of savings.

There are typically two distinguishing features of these types of rules: first they can be formulated from the data that has been captured (or will be captured) by the system in question, and second the business may vary the criteria encapsulated by the rule over time.

Architects and developers face a choice in the face of these criteria. Either rebuild and redeploy the components of the system that house the business rules logic, or integrate some rules engine technology that supports managing the logic separate from the code that depends on the results of those rules.

A well integrated rules solution should allow the the business logic of a system to be adjusted without requiring the system to be rebuilt and redeployed, resulting in both a more flexible system but also one that is more available and often more robust.

In the case of customer facing products, this can allow a single product to be adapted to distinct customers without necessitating the development of a custom build for that client.

Where Do Rules Engines Fit?

Implementing rules technologies is not without challenges. It’s not simply a matter of plugging a rules engine into a system and voila! it all just works.

Rules engines depend on the data that they are provided to operate. Architects must consider how that data will be made available to the engine, how will it flow towards the engine, how will it be combined to offer the maximum potential to the rules and how will the results from the rules engine flow back into the system. Not every business rule exhibits a high degree of volatility, as a result the effort required to move a particular rule into a rules engine environment should be weighed against the costs.

Rules engines must also be considered in the context of their intended users. Will the rules be configured by a technical resource, or is the intention to put that control into the hands of business users? The organisational structure of those business staff has a material impact on the design decisions that surround the rules engine.

An example might help here. If we think about an insurance company. At the very simplest level, there are two phases to the insurance business, risk evaluation and policy management. The risk evaluation phase determines whether the company is willing to enter into an agreement, whereas the policy management phase deals with everything that happens after the policy is signed.

Clearly the rules for these two phases are quite distinct and we would expect to see this reflected in the type of business rules with which they are concerned. We wouldn’t expect to see a risk analyst determine the rules around processing claims any more than we would expect a claims handler to determine the rules around risk analysis and underwriting.

Architects adopting rules engine technologies must respect this type of separation, whether it is through some form of authentication / authorisation mechanism, or by deploying distinct rules technologies into each domain (or some other means, there’s many ways to skin this particular cat).

Back to the question then, where do rules engines fit? The simplest answer is that it fits wherever is closest to the area of greatest volatility in business logic, or closest to the area requiring the greatest degree of flexibility in business logic.

How that manifests itself in the architecture depends on the overall architectural model. In some cases, embedding a rules engine within each domain makes sense, whereas other use cases may favour a more centralised rules engine with multiple connected data pipelines.

The result of these decisions bleeds into the information model, the security model, the user interfaces and of course influences orchestration within the system. The complexity that a rules engine can bring may explain why many systems are developed without integrating a rules engine, despite the apparent benefits such a technology can offer.

Microsoft’s Rules Engine

When evaluating Microsoft’s open source Rules Engine, I was looking at some specific criteria:

  1. Clear mechanism for defining the rules
  2. Separation of the rules from the engine
    Specifically, can the rules be modified without rebuilding the code hosting the rules engine.
  3. Support for flexible / variable data structures without rebuilding the code
  4. Support for complex rules including
    • Definition of custom rule code where basic expressions prove insufficient
    • Chaining of rules with branching and interdependencies between rules
    • Support for complex returns beyond simple yes / no or true / false
  5. Sufficient performance to handle a load of up to 50 requests per second
  6. Business friendly User Interface to support business users defining rules

Clear Rules Definition

The rules engine supports defining rules using a similar lambda syntax as is supported by .NET languages. For developers this should prove to be a fairly short learning curve. Non-technical users, who have familiarity with, for example, Excel macros should similarly find the definition of the rules quite straightforward.

Complex rules (see below) break this paradigm, but these should be the exception rather than the rule (no pun intended).

Separation of the rules from the engine

The rules are provided in a specifically structured JSON script. The rules engine imposes no restrictions on how the engine is provided with the rules script.

Implementing the engine requires the development of what the documentation describes as a wrapper which has the responsibility for hosting the rules engine, and marshalling both the rules scripts and the input data to the engine. This puts control over the desired flexibility entirely in the hands of the architects and developers implementing the rules engine.

Support for Flexible / Variable Data Structures

The rules engine imposes very few requirements on the data on which it operates. One or more inputs can be specified for each rules workflow, with those inputs being provided as simple dynamic types.

If the rules engine encounters a rule that relies on an element of data that does not exist in the provided input, then an error is raised.

Thus the only coupling that exists is between the rules script and the input data provided, with the rules engine only interpreting the input data based on the requirement of the rules script.

Support for Complex Rules

The rules engine supports the definition of quite complex rules, including chaining rules together in a fairly coherent manner. There are a number of approaches that can be employed to achieve the same results (have a look at the GitHub project for more details), which will either offer greater clarity or introduce more confusion.

Where the built in rules can’t support the decision desired by the user, a custom rule, written in C#, can be injected into the rules engine and referenced in the rules script. Naturally, this does break the intention of the rules engine approach as this introduces a dependency on custom built (and deployed) code.

There is similarly comprehensive support for building more complex outputs from the rules, allowing for a wide range of business rules and logic to be expressed.

Performance

The rules engine is a bit of a mixed bag here. In almost every test, the rules engine performed extremely well. I did find that this performance was highly contingent on the structure of the data being provided to the engine.

For basic data structures, the performance was well within acceptable levels, but when introducing generic dictionaries (for example), the engine’s performance degraded dramatically.

Business friendly User Interface to support business users defining rules

There is a separate project by Alex Reich here that offers a user interface component for building rules. Much like the rules engine itself, this is a component that can be integrated into the host system.

The UI, which continues to be under development offers basic features, and, being open source, offers the opportunity for developers to adapt it to their own needs. For basic rules definition, it is a reasonable solution, but falls short of the more sophisticated offerings like GoRules.

Conclusions

If you’re currently operating in the .NET ecosystem, the Microsoft Rules Engine offers a clean way to bring rules engine technology to your project. As the project matures, and the demands on the rules engine become more elaborate, a more comprehensive commercial solution may be required, particularly if the user interface requirements increase in priority.

It’s a relatively easy way to approach rules engine technologies, allowing architects and developers to explore the challenges of integrating this type of capability, on that basis alone it’s worth considering.

If you’re interested in looking at a demonstration of the capabilities of Microsoft’s Rules Engine, you can find the test code that I put together on GitHub here.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Website Powered by WordPress.com.

Up ↑