The Bitter Coder Tutorials, Binsor Style: Injecting Service Arrays
Previous posts in the series:
This post feeds off off Part 12 and is based on Alex’s post here. We are going to rework the last post and remove the decorator pattern. Instead, we’ll create a calculator that manages any number of other calculators, which are injected as an array.So, in keeping with my shameless plagirizing of Alex’s code, here is the abstract class for our new calculators:
namespace BitterCoder.Tutorials.Binsor.Core
{
public abstract class AbstractCalculator
{
public abstract decimal Calculate(decimal currentTotal, Order order);
}
}
using System.Linq;
namespace BitterCoder.Tutorials.Binsor.Core
{
public class TotalCalculator : AbstractCalculator
{
private static decimal CalculateTotal(Order order)
{
return order.Items.Sum(item => item.CostPerItem*item.Quantity);
}
public override decimal Calculate(decimal currentTotal, Order order)
{
return currentTotal + CalculateTotal(order);
}
}
}
namespace BitterCoder.Tutorials.Binsor.Core
{
public class GSTCostCalculatorNoDecorator : AbstractCalculator
{
private decimal _gstRate = 1.125m;
public decimal GstRate
{
get { return _gstRate; }
set { _gstRate = value; }
}
private static bool IsNewZealand(Order order)
{
return (order.CountryCode == "NZ");
}
public override decimal Calculate(decimal currentTotal, Order order)
{
if (IsNewZealand(order))
{
return (currentTotal*_gstRate);
}
return currentTotal;
}
}
}
namespace BitterCoder.Tutorials.Binsor.Core
{
public class ShippingCalculatorNoDecorator : AbstractCalculator
{
private decimal _fragileShippingPremium = 1.5m;
private decimal _shippingCost = 5.0m;
public decimal ShippingCost
{
get { return _shippingCost; }
set { _shippingCost = value; }
}
public decimal FragileShippingPremium
{
get { return _fragileShippingPremium; }
set { _fragileShippingPremium = value; }
}
private decimal GetShippingTotal(Order order)
{
decimal shippingTotal = 0;
return order.Items.Sum(item =>
{
decimal itemShippingCost = ShippingCost*item.Quantity;
if (item.IsFragile) itemShippingCost *= FragileShippingPremium;
return shippingTotal += itemShippingCost;
});
}
public override decimal Calculate(decimal currentTotal, Order order)
{
return currentTotal + GetShippingTotal(order);
}
}
}
public class DefaultCalculatorNoDecorator : ICostCalculator
{
private readonly AbstractCalculator[] _calculators;
public DefaultCalculatorNoDecorator(AbstractCalculator[] _calculators)
{
this._calculators = _calculators;
}
public decimal CalculateTotal(Order order)
{
decimal currentTotal = 0;
return _calculators.Sum(calc => calc.Calculate(currentTotal, order));
}
}
component "default.calculator", ICostCalculator,DefaultCalculatorNoDecorator: _calculators=[@total.calculatornodec,@shipping.calculatornodec,@gst.calculatornodec] component "total.calculatornodec", AbstractCalculator,TotalCalculator component "gst.calculatornodec", AbstractCalculator, GSTCostCalculatorNoDecorator: GstRate=Convert.ToDecimal(1.20) component "shipping.calculatornodec", AbstractCalculator, ShippingCalculatorNoDecorator: FragileShippingPremium=Convert.ToDecimal(0.0)Just like we did in our post on arrays, we inject an array of dependencies. Changing the order is just a matter of switching the order in the binsor. All good. Running the program gives the same output as the last post. Next post, which is the last in the series until Alex writes more (whew), is on the "Startable" facility.