using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NRules.IntegrationTests.TestAssets;
using NUnit.Framework;namespace NRules.IntegrationTests.TestAssets
{
public class MyFactType
{
public string TestProperty { get; set; }
public List<FactType1> Children { get; set; }
}
}
namespace NRules.IntegrationTests.TestRules
{
public class MyRule : BaseRule
{
public override void Define()
{
When()
.Exists<MyFactType>(model =>
model.Children[0].TestProperty == "true" &&
model.Children[1].TestProperty == "true" &&
model.Children[2].TestProperty == "true");
Then()
.Do(ctx => Notifier.RuleActivated())
.Do(ctx => Console.WriteLine("AN3 Fired!"));
}
}}namespace NRules.IntegrationTests.TestRules
{
[TestFixture]
public class MyTest : BaseRuleTestFixture
{
[Test]
public void Test1()
{
FactType1 c1 = new FactType1() { TestProperty = "false" };
FactType1 c2 = new FactType1() { TestProperty = "false" };
FactType1 c3 = new FactType1() { TestProperty = "false" };
MyFactType model = new MyFactType() { TestProperty = "Model", Children = new List<FactType1>() { c1, c2, c3 } };
Session.Insert(model);
Session.Fire();
AssertDidNotFire<MyRule>(); c1.TestProperty = "true";
c2.TestProperty = "true";
c3.TestProperty = "true";
Session.Update(model); // Why does this work?
Session.Fire();
AssertFiredOnce<MyRule>();
} [Test]
public void Test2()
{
FactType1 c1 = new FactType1() { TestProperty = "false" };
FactType1 c2 = new FactType1() { TestProperty = "false" };
FactType1 c3 = new FactType1() { TestProperty = "false" };
MyFactType model = new MyFactType() { TestProperty = "Model", Children = new List<FactType1>() { c1, c2, c3 } }; Session.Insert(model);
Session.Insert(c1);
Session.Insert(c2);
Session.Insert(c3);
Session.Fire();
AssertDidNotFire<MyRule>(); c1.TestProperty = "true";
c2.TestProperty = "true";
c3.TestProperty = "true";
Session.Update(c1);
Session.Update(c2);
Session.Update(c3);
Session.Fire(); // Why does this not work?
AssertFiredOnce<MyRule>();
} protected override void SetUpRules()
{
SetUpRule<MyRule>();
}
}
}
public class Property { public int Value { get; set; } public string Name { get; set; } }
public class PRequired : Rule { public override void Define() { Property property = null; When() .Match<Property>(() => property, p => p.Name == "P" && p.Value == 0); Then() .Do(context => Action1(context)); }
private void Action1(IContext context) { Console.WriteLine("P required"); } }
public class QRequired : Rule { public override void Define() { Property property = null; When() .Match<Property>(() => property, p => p.Name == "Q" && p.Value == 0); Then() .Do(context => Action1(context)); }
private void Action1(IContext context) { Console.WriteLine("Q required"); } }
public class XCalculation : Rule { public override void Define() { Property property_p = null; Property property_q = null; Property property_x = null; When() .Match<Property>(() => property_p, p => p.Name == "P" && p.Value != 0) .Match<Property>(() => property_q, q => q.Name == "Q" && q.Value != 0) .Match<Property>(() => property_x, x => x.Name == "X"); Then() .Do(context => Action1(context, property_p, property_q, property_x)); }
private void Action1(IContext context, Property p, Property q, Property x) { x.Value = p.Value + q.Value; context.Update(x); Console.WriteLine("X = " + x.Value); } } // Load rules var ruleRepository = new RuleRepository(); ruleRepository.Load("Ruleset", r => r.From( new []{ typeof(PRequired), typeof(QRequired), typeof(XCalculation) })); // Compile rules var factory = ruleRepository.Compile();
// Create a working session var session = factory.CreateSession(); Property p = new Property() { Name = "P", Value = 0}; Property q = new Property() { Name = "Q", Value = 0 }; Property x = new Property() { Name = "X", Value = 0 }; session.Insert(p); session.Insert(q); session.Insert(x);
session.Fire();
Console.WriteLine("Update P to 10"); p.Value = 10; session.Update(p); session.Fire();
Console.WriteLine("Update Q to 20"); q.Value = 20; session.Update(q); session.Fire(); // Calculation is done here
Console.WriteLine("Update P to 100"); p.Value = 100; session.Update(p); session.Fire(); // No calculation here!!!
Console.ReadKey();
Console.WriteLine("Update Q to 20");
q.Value = 20;
session.Update(q);
session.Fire();
// Calculation is done here
Console.WriteLine("Update P to 100");
p.Value = 100;
session.Retract(p);
session.Insert(p);
session.Fire();
// Calculation is done here again