Skip to content

Installation and basic usage

Paul Kent edited this page Apr 15, 2024 · 2 revisions

Section summary.

This section of the wiki provides information to get you started in the usage of the Conditionals library.

Installing

To install this library, download the latest version of Conditionals Nuget Package from nuget.org and reference it within your application.

Basic usage

  1. Initialise the 'ConditionEngine'
  2. Create a 'Rule' programmatically or via JSON.
  3. Add the rule to the 'ConditionEngine'.
  4. Get the rule data for the 'Conditions'.
  5. Evaluate the 'Rule'

Note: All the code below outlining the above steps is taken from the source code demo project within the area 01 - Contexts/1a-StoreCardApplication-Single-Data-Context

Initialising the condition engine

The condition engine can be used either with or without an IOC container, depending on your application's requirements.

If your application requires the use of custom evaluators with constructor-injected arguments or necessitates the use of dynamic event handlers, then you will need to associate the condition engine with your chosen IOC container. The condition engine uses a callback function for this association and utilizes it to resolve registered types when needed.

Depending on which areas within your application you would like to use the condition engine, it is probably a good idea to use your chosen IOC container and register the actual condition engine as a singleton or single instance. However, you can run multiple instances of the condition engine, each maintaining its own cache of rules if that better serves your purpose.

One of the condition engine's constructors accepts a Func<Type,dynamic> to allow the condition engine to call the IOC container.

Using the IOC container from the Microsoft.Extensions.DependencyInjection package, you can register the condition engine as a singleton and wire the callback function using:

services.AddSingleton<ConditionEngine>(provider => new ConditionEngine(type => provider.GetRequiredService(type));

// Or using the interface

services.AddSingleton<IConditionEngine,ConditionEngine>(provider => new ConditionEngine(type => provider.GetRequiredService(type)))

Or using Autofac (exactly as shown):

builder.Register<ConditionEngine>(c =>
{
    var context = c.Resolve<IComponentContext>();
    return new ConditionEngine(type => context.Resolve(type));
}).SingleInstance();

// Or using the interface

builder.Register(c =>
{
    var context = c.Resolve<IComponentContext>();
    return new ConditionEngine(type => context.Resolve(type));
}).As<IConditionEngine>().SingleInstance();

Without an IOC container:

var conditionEngine = new ConditionEngine();

Creating a rule

Assuming a standard approach of the condition engine being obtained by constructor injection and used within a method:

var applicantCondition = new PredicateCondition<StoreCardApplication>("ApplicantCondition", s => s.Age >= 18 && s.CountryOfResidence == "United Kingdom" && s.TotalOrders >= 5,
                                                                        failureMessage: "To be eligible for a store credit card you need to be over 18, living in the United Kingdom and have at least 5 completed orders against your account");
        
var applicationSet  = new ConditionSet<None>("ApplicantRequirements",None.Value, applicantCondition);
var storeCardRule   = new Rule<None>("StoreCreditCardRule",None.Value, applicationSet);

Adding the rule to the condition engine

We are continuing on from the example above, but alternatively, if we had the rule in a JSON formatted string we could have used the condition engines IngestRuleFromJson<T>(string ruleJson) or IngestRuleFromJson(string ruleJson) methods, see the ConditionEngine class. These methods transform the JSON into a Rule and then adds it using the AddOrUpdateRule method shown below.

_conditionEngine.AddOrUpdateRule(storeCardRule);

Get the rule data for the conditions

As we only have one condition, we only need a single data context. Conditions retrieve their data via the evaluate methods, which accept a ConditionData object. The ConditionData class holds an array of DataContext instances.We can create a new instance of the ConditionData class by passing in an array of data contexts. Alternatively, as in this instance, we can use the static method SingleContext as shown below, which accepts a single data object. For multiple conditions requiring multiple contexts and/or named contexts, we can use the ConditionDataBuilder to assist with this, see 01 - Contexts/1b-StoreCardApplication-Multiple-Data-Contexts.cs and 01 - Contexts/1c-SampleOrders-Named-Data-Contexts.

var applicantData = DemoData.StoreCardApplicationForCustomer(1);
var conditionData = ConditionData.SingleContext(applicantData!);

Evaluate the rule

var ruleResult = await _conditionEngine.EvaluateRule<None>(storeCardRule.RuleName, conditionData);

Note: You can also evaluate a rule, condition set or a condition by calling the 'Evaluate' method on the respective instance, without adding a rule to the condition engine. Please see 02 - Conditions/2a-Predicate-Conditions for more details.

Clone this wiki locally