IDependencyResolver(see https://github.com/NRules/NRules/wiki/Rule-Dependencies). Another approach is to inject dependencies into rules classes at rules instantiation time. In this case you need to implement
IRuleActivator(see https://github.com/NRules/NRules/wiki/Fluent-Rules-Loading#Rule-Activation). When you implement one or both of these interfaces, you can simply just forward resolution requests to your existing service container.
@snikolayev Is it possible to consume scoped services in MyRule (: Rule)? Currently it only work with Singleton service ( services.AddSingleton<IServiceTest, ServiceTest>(); ).
When I tried scoped services ( services.AddScoped<IServiceTest, ServiceTest>(); ) it threw an error as shown in the image above.
IDependencyResolver. When implementing the resolver, forward the resolution requests to the scoped service provider, instead of the root service provider. This also means you would have to create a new session per scope, create a dependency resolver for that scope and set it on that session.
RuleRepository, as that's only used with the rules defined using C# DSL. When using
RuleBuilder, you are getting back
IRuleDefinitions, and you can feed them directly to RuleCompiler.Compile method.
I also happen to have a question, I'm working on a project that requires going through rules and at some point having several choices (2-30 but possibly one choice leads to more choices down the line). I would like to be able to let the engine start from the current state and "trying" multiple solutions. I'm trying to figure out a way a simple and hopefully efficient way to do this. Here's what I experimented with/considered so far:
1) Considered using LinkedFacts, and while that handles new facts retraction, updates to existing facts wouldn't be reverted. So make a log of updates and revert manually?
2) Deep-copy all facts, make choice, continue execution. Once run is over, retract all, insert all fact copies, make new choice, repeat.
3) Deep-copy all facts, halt current session, create new session for each choice, starting with the fact copies.
I have the impression I'm missing a clever way to use the framework to help me. Additionally, doing this in a way where I can leverage already calculated fact combinations would be great as there are combinations that would be repeated.
The reason I'm trying to use NRules for this is that new and updated facts tend to trigger a limited number of rules and fact changes. For reference the "scale" I'm working with is along the lines of ~50-200 facts and probably ~50-200 rules.
Thanks for the previous answer. Now I'm trying to figure out how to deal with
ActionTrigger. Consider the following CODE
When I run it, I get the expected output:
But if I remove
ActionTrigger.Reactivated, only the first line is printed. The engine doesn't react to retraction. Why is that happening?
1 argumentsList) at NRules.RuleSharp.PrimaryExpressionBuilder.Method(List1 argumentsList)
1.Visit(IParseTree tree) at NRules.RuleSharp.ExpressionParser.VisitUnary_expression(Unary_expressionContext context) at NRules.RuleSharp.Parser.RuleSharpParser.Unary_expressionContext.Accept[TResult](IParseTreeVisitor1 visitor)
1.Visit(IParseTree tree) at NRules.RuleSharp.ExpressionParser.VisitMultiplicative_expression(Multiplicative_expressionContext context) at NRules.RuleSharp.Parser.RuleSharpParser.Multiplicative_expressionContext.Accept[TResult](IParseTreeVisitor1 visitor)
1.Visit(IParseTree tree) at NRules.RuleSharp.ExpressionParser.VisitAdditive_expression(Additive_expressionContext context) at NRules.RuleSharp.Parser.RuleSharpParser.Additive_expressionContext.Accept[TResult](IParseTreeVisitor1 visitor)
1.VisitChildren(IRuleNode node) at NRules.RuleSharp.Parser.RuleSharpParserBaseVisitor1.VisitShift_expression(Shift_expressionContext context)
1.Visit(IParseTree tree) at NRules.RuleSharp.ExpressionParser.VisitRelational_expression(Relational_expressionContext context) at NRules.RuleSharp.Parser.RuleSharpParser.Relational_expressionContext.Accept[TResult](IParseTreeVisitor1 visitor)
1.Visit(IParseTree tree) at NRules.RuleSharp.ExpressionParser.VisitEquality_expression(Equality_expressionContext context) at NRules.RuleSharp.Parser.RuleSharpParser.Equality_expressionContext.Accept[TResult](IParseTreeVisitor1 visitor)
1.Visit(IParseTree tree) at NRules.RuleSharp.ExpressionParser.VisitAnd_expression(And_expressionContext context) at NRules.RuleSharp.Parser.RuleSharpParser.And_expressionContext.Accept[TResult](IParseTreeVisitor1 visitor)
1.Visit(IParseTree tree) at NRules.RuleSharp.ExpressionParser.VisitExclusive_or_expression(Exclusive_or_expressionContext context) at NRules.RuleSharp.Parser.RuleSharpParser.Exclusive_or_expressionContext.Accept[TResult](IParseTreeVisitor1 visitor)
1.Visit(IParseTree tree) at NRules.RuleSharp.ExpressionParser.VisitInclusive_or_expression(Inclusive_or_expressionContext context) at NRules.RuleSharp.Parser.RuleSharpParser.Inclusive_or_expressionContext.Accept[TResult](IParseTreeVisitor1 visitor)
1.Visit(IParseTree tree) at NRules.RuleSharp.ExpressionParser.VisitConditional_and_expression(Conditional_and_expressionContext context) at NRules.RuleSharp.Parser.RuleSharpParser.Conditional_and_expressionContext.Accept[TResult](IParseTreeVisitor1 visitor)
import model.LineItem; import model.Brand; import model.Market; import model.Seller; global java.util.List coupons; rule "Rule 1" when exists LineItem(category == "PC", market in (Market.MARKETPLACE1), brand in (Brand.ACER)) then coupons.add("#PC0001"); end
Then() .Do(ctx => SendEmailNotification(currentCartItem));