Console App based on the Getting Started page Not Working

39 views
Skip to first unread message

Mark McFadden

unread,
Oct 25, 2019, 8:16:04 AM10/25/19
to NRules Users

 have created a Console App based on the Getting Started page at https://github.com/NRules/NRules/wiki/Getting-Started

I am not seeing the Customer object's NotifyAboutDiscount string output "Customer {0} was notified about a discount." What am I doing wrong?


Here are my models:

using System;

namespace NRulesTest
{
   
public class Customer
   
{
       
public string Name { get; private set; }
       
public bool IsPreferred { get; set; }

       
public Customer(string name)
       
{
           
Name = name;
       
}

       
public void NotifyAboutDiscount()
       
{
           
Console.WriteLine("Customer {0} was notified about a discount", Name);
       
}
   
}

   
public class Order
   
{
       
public int Id { get; private set; }
       
public Customer Customer { get; private set; }
       
public int Quantity { get; private set; }
       
public double UnitPrice { get; private set; }
       
public double PercentDiscount { get; internal set; }
       
public bool IsDiscounted { get { return PercentDiscount > 0; } }


       
public double Price
       
{
           
get { return UnitPrice * Quantity * (1.0 - PercentDiscount / 100.0); }
       
}

       
public bool IsOpen { get; internal set; }

       
public Order(int id, Customer customer, int quantity, double unitPrice, bool isOpen = false, double percentDiscount = 0.0)
       
{
           
Id = id;
           
Customer = customer;
           
Quantity = quantity;
           
UnitPrice = unitPrice;
           
IsOpen = isOpen;
           
PercentDiscount = percentDiscount;
       
}

       
public void ApplyDiscount(double percentDiscount)
       
{
           
PercentDiscount = percentDiscount;
       
}
   
}
}


DiscountNotificationRule class:


using NRules.Fluent.Dsl;

namespace NRulesTest
{
   
class DiscountNotificationRule : Rule
   
{
       
public override void Define()
       
{
           
Customer customer = null;
           
When()
               
.Match<Customer>(() => customer)
               
.Exists<Order>(o => o.Customer == customer, o => o.PercentDiscount > 0.0);
           
Then()
               
.Do(_ => customer.NotifyAboutDiscount());
       
}
   
}
}

PreferredCustomerDiscountRule class:

using NRules.Fluent.Dsl;
using System.Collections.Generic;
using System.Linq;


namespace NRulesTest
{
   
class PreferredCustomerDiscountRule : Rule
   
{
       
public override void Define()
       
{
           
Customer customer = null;
           
IEnumerable<Order> orders = null;

           
When()
               
.Match<Customer>(() => customer, c => c.IsPreferred)
               
.Query(() => orders, x => x
                   
.Match<Order>(
                        o
=> o.Customer == customer,
                        o
=> o.IsOpen,
                        o
=> !o.IsDiscounted)
                   
.Collect()
                   
.Where(c => c.Any()));
           
Then()
               
.Do(ctx => ApplyDiscount(orders, 10.0))
               
.Do(ctx => ctx.UpdateAll(orders));
       
}
       
private static void ApplyDiscount(IEnumerable<Order> orders, double discount)
       
{
           
foreach (var order in orders)
           
{
                order
.ApplyDiscount(discount);
           
}
       
}
   
}
}

Program.cs with the entry method:

using NRules;
using NRules.Fluent;
using System;

namespace NRulesTest
{
   
class Program
   
{
       
static void Main(string[] args)
       
{
           
//Console.WriteLine("Hello World!");
           
var repository = new RuleRepository();
            repository
.Load(x => x.From(typeof(PreferredCustomerDiscountRule).Assembly));

           
//Compile rules
           
var factory = repository.Compile();

           
//Create a working session
           
var session = factory.CreateSession();

           
//Load domain model
           
var customer = new Customer("John Doe") { IsPreferred = true };
           
var order1 = new Order(123456, customer, 2, 25.0, true);
           
var order2 = new Order(123457, customer, 1, 100.0, true);

           
//Insert facts into rules engine's memory
            session
.Insert(customer);
            session
.Insert(order1);
            session
.Insert(order2);

           
//Start match/resolve/act cycle
            session
.Fire();

           
Console.ReadKey();
       
}
   
}
}

As you can surmise, I am new to NRules. Thanks for your help.

Sergiy Nikolayev

unread,
Oct 27, 2019, 11:50:31 PM10/27/19
to NRules Users
Your rule classes are not public, so they are not getting discovered when loading rules from assembly

Mark McFadden

unread,
Oct 28, 2019, 12:56:32 PM10/28/19
to NRules Users
Thanks. Knew it was something simple.
Reply all
Reply to author
Forward
0 new messages