using System.Collections.Generic;
using Microsoft.Practices.Unity;
public static void Main(string[] args)
IUnityContainer uContainer = new UnityContainer()
.RegisterType<IProductRepository, ProductRepository>();
ProductService service = uContainer.Resolve<ProductService>();
List<int> productIds = new List<int>();
IList<Product> products = service.CalculateProductsPrice(productIds);
foreach (Product p in products)
Console.WriteLine(" Product Name {0} Cost {1} Sales Tax {2}", p.Name, p.Price.FinalSellingPrice, p.Price.SalesTax);
Console.WriteLine(" Total Cost {0} Total Sales Tax {1}", products.Sum(x => x.Price.FinalSellingPrice), products.Sum(x => x.Price.SalesTax));
public interface ISalesTaxStrategy
decimal ApplySalesTaxTo(decimal OriginalSalePrice);
public interface IProductRepository
Product FindById(int id);
public Product(int id, SalesTaxType category, string name, Price price)
public int Id { get; set; }
public SalesTaxType Category { get; set; }
public string Name { get; set; }
public Price Price { get; set; }
private ISalesTaxStrategy _salesTaxStrategy = new NullTaxStrategy();
private decimal _sellingPrice;
public Price(decimal SellingPrice)
_sellingPrice = SellingPrice;
public void SetSalesTaxStrategy(ISalesTaxStrategy SalesTaxStrategy)
_salesTaxStrategy = SalesTaxStrategy;
public decimal FinalSellingPrice
get { return _salesTaxStrategy.ApplySalesTaxTo(_sellingPrice); }
if (FinalSellingPrice > _sellingPrice)
return (FinalSellingPrice - _sellingPrice);
public class NullTaxStrategy : ISalesTaxStrategy
public decimal ApplySalesTaxTo(decimal OriginalSalePrice)
return OriginalSalePrice;
public class CategoryATaxStrategy : ISalesTaxStrategy
public decimal ApplySalesTaxTo(decimal OriginalSalePrice)
decimal price = OriginalSalePrice;
public class CategoryBTaxStrategy : ISalesTaxStrategy
public decimal ApplySalesTaxTo(decimal OriginalSalePrice)
decimal price = OriginalSalePrice;
public static class SalesTaxFactory
public static ISalesTaxStrategy GetSalesTaxStrategyFor(SalesTaxType salesTaxType)
case SalesTaxType.CategoryA:
return new CategoryATaxStrategy();
case SalesTaxType.CategoryB:
return new CategoryBTaxStrategy();
return new NullTaxStrategy();
#region Repository Classes
public class ProductRepository : IProductRepository
List<Product> products = new List<Product>();
public ProductRepository()
Product pA = new Product(1, SalesTaxType.CategoryA, "PCategoryA", new Price(100M));
Product pB = new Product(2, SalesTaxType.CategoryB, "PCategoryB", new Price(100M));
Product pC = new Product(3, SalesTaxType.CategoryC, "PCategoryC", new Price(100M));
#region IProductRepository Members
public Product FindById(int id)
Product found = products.Where(x => x.Id == id).First();
throw new ArgumentNullException();
public class MockProductRepository : IProductRepository
List<Product> products = new List<Product>();
public MockProductRepository()
Product pA = new Product(1, SalesTaxType.CategoryA, "PCategoryA", new Price(100M));
Product pB = new Product(2, SalesTaxType.CategoryB, "PCategoryB", new Price(100M));
Product pC = new Product(3, SalesTaxType.CategoryC, "PCategoryC", new Price(100M));
#region IProductRepository Members
public Product FindById(int id)
Product found = products.Where(x => x.Id == id).First();
throw new ArgumentNullException();
public class ProductService
private IProductRepository _productRepository;
public ProductService(IProductRepository productRepository)
_productRepository = productRepository;
public IList<Product> CalculateProductsPrice(List<int> productIds)
IList<Product> products = new List<Product>();
foreach (int id in productIds)
Product p = _productRepository.FindById(id);
ISalesTaxStrategy strategy = SalesTaxFactory.GetSalesTaxStrategyFor(p.Category);
p.Price.SetSalesTaxStrategy(strategy);