Skip to content

Commit 07311ca

Browse files
authored
Merge pull request ardalis#14 from ardalis/ardalis/apply-rules
Remove old version and udpate to use reflection to load rules
2 parents 0e75648 + fd26473 commit 07311ca

File tree

4 files changed

+84
-152
lines changed

4 files changed

+84
-152
lines changed

DesignPatternsInCSharp/RulesEngine/Before/Customer.cs

Lines changed: 0 additions & 11 deletions
This file was deleted.

DesignPatternsInCSharp/RulesEngine/Before/DiscountCalculator.cs

Lines changed: 0 additions & 47 deletions
This file was deleted.

DesignPatternsInCSharp/RulesEngine/Before/DiscountCalculator_CalculateDiscountPercentage.cs

Lines changed: 0 additions & 75 deletions
This file was deleted.
Lines changed: 84 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,127 @@
11
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Diagnostics.Contracts;
5+
using System.Linq;
26

37
namespace DesignPatternsInCSharp.RulesEngine.Discounts
48
{
5-
public class DiscountCalculator
9+
// View History
10+
// https://github.githistory.xyz/ardalis/DesignPatternsInCSharp/blob/master/DesignPatternsInCSharp/RulesEngine/Discounts/DiscountCalculator.cs
11+
public interface IDiscountRule
612
{
7-
public decimal CalculateDiscountPercentage(Customer customer)
13+
decimal CalculateDiscount(Customer customer, decimal currentDiscount);
14+
}
15+
16+
public class FirstTimeCustomerRule : IDiscountRule
17+
{
18+
public decimal CalculateDiscount(Customer customer, decimal currentDiscount)
819
{
9-
bool isBirthday = customer.DateOfBirth.HasValue && customer.DateOfBirth.Value.Month == DateTime.Today.Month && customer.DateOfBirth.Value.Day == DateTime.Today.Day;
1020
if (!customer.DateOfFirstPurchase.HasValue)
1121
{
1222
return .15m;
1323
}
14-
else
24+
return 0;
25+
}
26+
}
27+
28+
public class LoyalCustomerRule : IDiscountRule
29+
{
30+
public decimal CalculateDiscount(Customer customer, decimal currentDiscount)
31+
{
32+
if (customer.DateOfFirstPurchase.HasValue)
1533
{
1634
if (customer.DateOfFirstPurchase.Value < DateTime.Now.AddYears(-15))
1735
{
18-
if (isBirthday) return .25m;
1936
return .15m;
2037
}
2138
if (customer.DateOfFirstPurchase.Value < DateTime.Now.AddYears(-10))
2239
{
23-
if (isBirthday) return .22m;
2440
return .12m;
2541
}
2642
if (customer.DateOfFirstPurchase.Value < DateTime.Now.AddYears(-5))
2743
{
28-
if (isBirthday) return .20m;
2944
return .10m;
3045
}
31-
if (customer.DateOfFirstPurchase.Value < DateTime.Now.AddYears(-2) &&
32-
!customer.IsVeteran)
46+
if (customer.DateOfFirstPurchase.Value < DateTime.Now.AddYears(-2))
3347
{
34-
if (isBirthday) return .18m;
3548
return .08m;
3649
}
37-
if (customer.DateOfFirstPurchase.Value < DateTime.Now.AddYears(-1) &&
38-
!customer.IsVeteran)
50+
if (customer.DateOfFirstPurchase.Value < DateTime.Now.AddYears(-1))
3951
{
40-
if (isBirthday) return .15m;
4152
return .05m;
4253
}
4354
}
55+
return 0;
56+
}
57+
}
4458

59+
public class VeteranRule : IDiscountRule
60+
{
61+
public decimal CalculateDiscount(Customer customer, decimal currentDiscount)
62+
{
4563
if (customer.IsVeteran)
4664
{
47-
if (isBirthday) return .20m;
4865
return .10m;
4966
}
50-
51-
if(customer.DateOfBirth < DateTime.Now.AddYears(-65))
67+
return 0;
68+
}
69+
}
70+
public class SeniorRule : IDiscountRule
71+
{
72+
public decimal CalculateDiscount(Customer customer, decimal currentDiscount)
73+
{
74+
if (customer.DateOfBirth < DateTime.Now.AddYears(-65))
5275
{
53-
if (isBirthday) return .15m;
5476
return .05m;
5577
}
78+
return 0;
79+
}
80+
}
5681

57-
if (isBirthday) return .10m;
82+
public class BirthdayRule : IDiscountRule
83+
{
84+
public decimal CalculateDiscount(Customer customer, decimal currentDiscount)
85+
{
86+
bool isBirthday = customer.DateOfBirth.HasValue && customer.DateOfBirth.Value.Month == DateTime.Today.Month && customer.DateOfBirth.Value.Day == DateTime.Today.Day;
5887

59-
return 0;
88+
if (isBirthday) return currentDiscount + 0.10m;
89+
return currentDiscount;
90+
}
91+
}
92+
93+
public class DiscountRuleEngine
94+
{
95+
List<IDiscountRule> _rules = new List<IDiscountRule>();
96+
97+
public DiscountRuleEngine(IEnumerable<IDiscountRule> rules)
98+
{
99+
_rules.AddRange(rules);
100+
}
101+
102+
public decimal CalculateDiscountPercentage(Customer customer)
103+
{
104+
decimal discount = 0m;
105+
foreach(var rule in _rules)
106+
{
107+
discount = Math.Max(discount, rule.CalculateDiscount(customer, discount));
108+
}
109+
return discount;
110+
}
111+
}
112+
113+
public class DiscountCalculator
114+
{
115+
public decimal CalculateDiscountPercentage(Customer customer)
116+
{
117+
var ruleType = typeof(IDiscountRule);
118+
IEnumerable<IDiscountRule> rules = this.GetType().Assembly.GetTypes()
119+
.Where(p => ruleType.IsAssignableFrom(p) && !p.IsInterface)
120+
.Select(r => Activator.CreateInstance(r) as IDiscountRule);
121+
122+
var engine = new DiscountRuleEngine(rules);
123+
124+
return engine.CalculateDiscountPercentage(customer);
60125
}
61126
}
62127
}

0 commit comments

Comments
 (0)