Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Behavioral/ChainOfResponsibility/RuleEngine/Dto/PriceDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Entity;

namespace Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Dto
{
public record PriceModel
{
public decimal Price { get; set; }

public Source Source { get; set; }
}
}
16 changes: 16 additions & 0 deletions Behavioral/ChainOfResponsibility/RuleEngine/Entity/Product.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Entity
{
public class Product
{
public Product()
{
Sources=new List<ProductSource>();
}
public int Id { get; set; }

public decimal Price { get; set; }
public decimal SalePrice { get; set; }

public ICollection<ProductSource> Sources { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Entity
{
public class ProductSource
{
public Source Source { get; set; }

public Product Product { get; set; }

public string Url { get; set; }

public DateTime LastUpdatedOn { get; set; }
}
}
11 changes: 11 additions & 0 deletions Behavioral/ChainOfResponsibility/RuleEngine/Entity/Source.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Entity
{
public enum Source
{
Amazon,
Decathlon,
DigiKala,
Torob,
Trendyol
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Dto;
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Entity;
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Interface;

namespace Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Infra
{
public class PriceRuleEngine
{
private readonly IEnumerable<IPriceRule> _rules;

public PriceRuleEngine(IEnumerable<IPriceRule> rules)
{
_rules=rules;
}

public PriceModel CalculatePrice(Product product)
{
var price=new PriceModel();
foreach (var rule in _rules)
{
price = rule.Calculate(product, price);
}

return price;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Dto;
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Entity;
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Interface;

namespace Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Infra.PriceRules
{
public class AmazonRule : IPriceRule
{
public int Priority { get; set; } = 1;
public PriceModel Calculate(Product product, PriceModel price)
{
//fetch the price from Amazon and get the lower price
return new PriceModel
{
Source = Source.Amazon,
Price = 19_000
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Dto;
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Entity;
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Interface;

namespace Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Infra.PriceRules
{
public class DecathlonRule : IPriceRule
{
public int Priority { get; set; } = 2;
public PriceModel Calculate(Product product, PriceModel price)
{
//fetch the price from Decathlon and get the lower price
return new PriceModel
{
Source = Source.Decathlon,
Price = 16_000
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Dto;
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Entity;
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Interface;

namespace Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Infra.PriceRules
{
public class DigiKalaRule : IPriceRule
{
public int Priority { get; set; } = 3;
public PriceModel Calculate(Product product, PriceModel price)
{
//fetch the price from DigiKala and get the lower price
return new PriceModel
{
Source = Source.DigiKala,
Price = 15_000
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Dto;
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Entity;
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Interface;

namespace Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Infra.PriceRules
{
public class TorobRule : IPriceRule
{
public int Priority { get; set; } = 4;
public PriceModel Calculate(Product product, PriceModel price)
{
//fetch the price from Torob and get the lower price
return new PriceModel
{
Source = Source.Torob,
Price = 10_000
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Dto;
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Entity;
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Interface;

namespace Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Infra.PriceRules
{
public class TrendyolRule : IPriceRule
{
public int Priority { get; set; } = 2;
public PriceModel Calculate(Product product, PriceModel price)
{
//fetch the price from Trendyol and get the lower price
return new PriceModel
{
Source = Source.Trendyol,
Price = 8_000
};
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Dto;
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Entity;

namespace Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Interface
{
public interface IPriceRule
{
public int Priority { get; set; }

PriceModel Calculate(Product product,PriceModel price);
}
}
40 changes: 39 additions & 1 deletion Behavioral/ChainOfResponsibility/RuleEngine/Program.cs
Original file line number Diff line number Diff line change
@@ -1,2 +1,40 @@
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Entity;
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Infra;
using Thisisnabi.DesignPattern.Behavioral.ChainOfResponsibility.RuleEngine.Interface;
using System.Reflection;

var product = new Product
{
Sources = new List<ProductSource>
{
new()
{
Source = Source.Torob,
Url = "https://torob.com/.."
},
new ProductSource
{
Source = Source.DigiKala,
Url = "https://digikala.com/.."
},
new ProductSource
{
Source = Source.Amazon,
Url = "https://Amazon.com/.."
}
}
};
var ruleType = typeof(IPriceRule);

var rules = Assembly.GetExecutingAssembly().GetTypes()
.Where(p => ruleType.IsAssignableFrom(p) && !p.IsInterface)
.Select(q => Activator.CreateInstance(q) as IPriceRule)
.OrderBy(p => p.Priority).ToList();

var engine = new PriceRuleEngine(rules);

var result = engine.CalculatePrice(product);

Console.WriteLine($"The lowest price is :{result.Price} and available on :{result.Source} ");