So in the previous blog we have created IDiscountStrategy and applied it to NullDiscountStrategy and TradeDiscountStrategy Classes.
We have only created Discount Pattern here… and we need to apply this on Price Object and driving factor regarding which Discount Pattern to be applied will be decided by Customer Type.So in order to apply Discount pattern on Price object lets create DiscountFactory class which does this job.
public static class DiscountFactory { public static IDiscountStrategy GetDiscountStrategyFor(CustomerType customerType) { switch (customerType) { case CustomerType.Trade: return new TradeDiscountStrategy(); default: return new NullDiscountStrategy(); } } }
With discount Strategies in place .. now lets implement Price Object…
public class Price { private IDiscountStrategy _discountStrategy = new NullDiscountStrategy(); private decimal _rrp; private decimal _sellingPrice; public Price(decimal sellingPrice,decimal rrp) { _rrp = rrp; _sellingPrice = sellingPrice; } public void SetDiscountStrategyTo(IDiscountStrategy discountStrategy) { _discountStrategy = discountStrategy; } public decimal SellingPrice { get { return _discountStrategy.ApplyExternalDiscountsTo(_sellingPrice); } } public decimal RRP { get { return _rrp; } } public decimal Discount { get { if(RRP>SellingPrice) { return RRP - SellingPrice; } else { return 0; } } } public decimal Savings { get { if (RRP > SellingPrice) return (1 - SellingPrice / RRP); else return 0; } } }
Now we need to apply this discount Pattern to Products List which we will do thru an Extension method
public static class ProductListExtensionMethod { public static void Apply(this IList<Product>;products, IDiscountStrategy discountStrategy) { products.ToList().ForEach (p => p.Price.SetDiscountStrategyTo(discountStrategy)); } }
Domain Service
with Domain in place.. we need to have a service in domain so that client(typically service layer ) can communicate with Domain layer.. lets create a Domain Service(name it Product Service)
public class ProcuctService { private IProductRepository _productRepository; public ProcuctService(IProductRepository productRepository) { _productRepository = productRepository; } public IList<Product? GetAllProductsFor(CustomerType customerType) { IDiscountStrategy discountStrategy = DiscountFactory.GetDiscountStrategyFor(customerType); IList<Product> products = _productRepository.FindAll(); products.Apply(discountStrategy); return products; } }
Now Domain Service layer is in player.. lts implement Service layer which would communicate with Domain Service layer
public class ProductService { private model.ProcuctService _productService; public ProductService(model.ProcuctService productService) { _productService = productService; } public ProductListResponse GetAllProductsFor( ProductListRequests productListRequest) { ProductListResponse productListResponce = new ProductListResponse(); try { IList<model.Product> productEntities = _productService.GetAllProductsFor(productListRequest.CustomerType); productListResponce.Products = productEntities.ConvertToProductListViewModel(); productListResponce.Success = true; } catch (Exception ex) { productListResponce.Success = false; productListResponce.Message = ex.Message.ToString(); throw; } return productListResponce; } }