Skip to content

C# Snippets

Full Stack edited this page May 9, 2025 · 1 revision

Pattern for Rule Engine

read

A Rule Engine in C# can be implemented using the Strategy Design Pattern or a combination of patterns like Chain of Responsibility and Specification Pattern. Below is an example of a Rule Engine using the Strategy Design Pattern.


Design Pattern: Rule Engine

  1. Context: A RuleEngine class that executes rules.
  2. Strategy: Each rule is implemented as a separate class implementing a common interface.
  3. Example Scenario: A discount system where different rules apply based on customer type, order amount, etc.

Implementation

Step 1: Define the Rule Interface

Each rule will implement this interface.

public interface IRule
{
    bool IsApplicable(Order order);
    void Apply(Order order);
}

Step 2: Create the Rule Engine

The RuleEngine class will execute all applicable rules.

using System.Collections.Generic;

public class RuleEngine
{
    private readonly List<IRule> _rules;

    public RuleEngine()
    {
        _rules = new List<IRule>();
    }

    public void AddRule(IRule rule)
    {
        _rules.Add(rule);
    }

    public void Execute(Order order)
    {
        foreach (var rule in _rules)
        {
            if (rule.IsApplicable(order))
            {
                rule.Apply(order);
            }
        }
    }
}

Step 3: Define the Order Class

This represents the input data for the rules.

public class Order
{
    public string CustomerType { get; set; }
    public decimal OrderAmount { get; set; }
    public decimal Discount { get; set; }
}

Step 4: Implement Specific Rules

Each rule implements the IRule interface.

public class HighValueOrderRule : IRule
{
    public bool IsApplicable(Order order)
    {
        return order.OrderAmount > 1000;
    }

    public void Apply(Order order)
    {
        order.Discount += 100; // Apply a $100 discount
    }
}

public class LoyalCustomerRule : IRule
{
    public bool IsApplicable(Order order)
    {
        return order.CustomerType == "Loyal";
    }

    public void Apply(Order order)
    {
        order.Discount += order.OrderAmount * 0.1m; // 10% discount
    }
}

Step 5: Use the Rule Engine

Create an instance of the RuleEngine, add rules, and execute them.

using System;

class Program
{
    static void Main()
    {
        // Create an order
        var order = new Order
        {
            CustomerType = "Loyal",
            OrderAmount = 1200
        };

        // Create the rule engine and add rules
        var ruleEngine = new RuleEngine();
        ruleEngine.AddRule(new HighValueOrderRule());
        ruleEngine.AddRule(new LoyalCustomerRule());

        // Execute the rules
        ruleEngine.Execute(order);

        // Output the result
        Console.WriteLine($"Final Discount: {order.Discount:C}");
    }
}

Output

For an order with CustomerType = "Loyal" and OrderAmount = 1200:

Final Discount: $220.00

Advantages of This Design

  1. Extensibility: Adding new rules is easy—just create a new class implementing IRule.
  2. Separation of Concerns: Each rule is encapsulated in its own class.
  3. Reusability: Rules can be reused across different contexts.

This approach is clean, scalable, and adheres to the Open/Closed Principle.

Clone this wiki locally