Passing parameters to Rules

243 views
Skip to first unread message

Mike Doonsebury

unread,
Sep 18, 2018, 2:14:02 PM9/18/18
to NRules Users
I have a rule I'm trying to implement.  The same rule can be run for different accounts and each of the different accounts is going to have a different parameter associated with it.  Abstractly, it would look like this:

public bool IsAlphaValid(double alpha)
{
           
Domain.CurrentPortfolioRow currentPortfolioRow = null;


           
When()
               
.Match<Domain.CurrentPortfolioRow>(() => currentPortfolioRow, cpr => cpr.Alpha > alpha)
           
Then()

               
.Do(_ => System.Diagnostics.Debug.WriteLine("OptimalAlpha: Alpha is valid."));
}




Any ideas how to implement this with NRules?

Sergiy Nikolayev

unread,
Sep 18, 2018, 3:57:05 PM9/18/18
to NRules Users
Hi Mike,

There are multiple ways you can parameterize rules.
1. You can inject parameters directly into the rule during rule creation by taking over rule activation. This won't work for your use case, because you want the parameters to be fact-dependent, but I just wanted to give this option for completeness.
2. You can represent parameters as facts, insert them into the session, and then match them in the rule. In this case, you can insert different parameter values for different accounts into the rules session, match those parameters and join to your other fact in the rule.
3. You can have a service (say ParameterProvider) that you inject into your rule (manually, or via a DI container, see rule activation), and then fetch the parameter value from that service for a given account number.

Sergiy

Larry LeBron

unread,
Feb 25, 2019, 8:54:13 PM2/25/19
to NRules Users
Hi Sergiy,

Just to make sure I understand properly, in option 3, you say:

3. You can have a service (say ParameterProvider) that you inject into your rule (manually, or via a DI container, see rule activation), and then fetch the parameter value from that service for a given account number.


Let's say I have a scenario where my rule's When() conditions compare a value in a fact to something in the parameter, like in this example from above (changing to an int for simplicity):

 When() 
.Match<Domain.CurrentPortfolioRow>(() => currentPortfolioRow, cpr => cpr.Num > paramNum)

Now let's say that, at start we have:

cpr.Num = 1
paramNum = 100

Obviously, when I fire this session, the rule won't meet the condition.

However, if I then change paramNum to 0, firing again still won't cause the rule to match, right? Since the paramNum isn't stored in the rete and isn't updated as a fact.

Is there any way to inform the session that a value like this has been updated and should therefore be retested during Fire()? I saw your the note in the dependency documentation regarding not supporting dependencies for conditions, so I assume not?

Obviously this would just work if paramNum was coming from a fact so presumably that's the proper way to do it. I just want to make sure I'm not missing something in your suggestion of option 3 in the original response.

Thanks!
 

Sergiy Nikolayev

unread,
Feb 25, 2019, 9:12:43 PM2/25/19
to NRules Users
You are correct - if you want rules engine to react to parameter changes and reevaluate corresponding conditions, your only option is #2 - to represent parameters as facts.

Larry LeBron

unread,
Feb 26, 2019, 1:25:00 AM2/26/19
to NRules Users
Great, thanks for confirming!
Reply all
Reply to author
Forward
0 new messages