Introduction
Architecture has an elegance and a purpose. For a given set of data, consider rows of a table consisting of meaningful data. Like in a loan, a financial product, there can be a number of different types of rules, like the total amount should be greater than 10000, the total amount should be greater than the balance amount, client name should not be blank and so on. Architecture in this article assumes that assorted such rules can be classified in classes and can be reused many times later, and if the need arises, the new type of rules can be created and integrated into the application. In this article, I will discuss only two types of rules: validation of a field and comparison of any two fields of the same dataset.
Approach
There are mainly 4 classes in this small application.
- FpProduct, representing a financial product, this represents entity.
- FpProductsEntities, this represents the collection of financial product ie. FpProduct.
- ClassVisitValidateField to validate the fields of FpProduct in collection named FpProductsEntities
- ClassVisitCompareFields to compare between two fields of FpProduct in FpProductsEntities.
The 3 and 4 Classes are rules based upon the FpProductsEntities that will be filtered.
The desire is to keep rules unknowledgeable to fields of entity upon which it will apply, and that made the reason to leverage the expression tree to achieve the same.
Code
Below is the implementation of Classes and Interfaces used in the application.
- // FpProduct: this is our entity.For simplicity sake i have taken only few columns from
- // table Financial Product to represent the entity.
- class FpProduct
- {
- public string ProductiD { get; set; }
- public string ProductName { get; set; }
- public string ProductType { get; set; }
- public double ProductTotalAmount { get; set; }
- public double ProductBalanceAmount { get; set; }
- public int ProductTenure { get; set; }
- public FpProduct(string Productid, string ProdName, string ProdType, double ProdTotalAmount,
- double ProdBalanceAmount, int ProdTenure)
- {
- ProductiD = Productid;
- ProductName = ProdName;
- ProductType = ProdType;
- ProductTotalAmount = ProdTotalAmount;
- ProductBalanceAmount = ProdBalanceAmount;
- ProductTenure = ProdTenure;
- }
- public override string ToString()
- {
- return "Product id: "+ProductiD + " Product Name:" + ProductName+ " Product Type: "+ ProductType +
- " Product Total Amount: "+ProductTotalAmount+ " Product Balance Amount: "+ProductBalanceAmount + " Product Tenure: " +ProductTenure;
- }
- }
- // FpProductsEntities: This is our collection of FpProduct and this will also contain
- // the rules.Few things needed to note about the Class are:
- // 1. The class consists of the collection of FpProduct
- // 2. The Class has exposés functionality LoadData() to load FpProduct.
- // You can Overide it with with your own data load method.
- // 3. The Class exposes functionality to attach rules.
- // 4. It Implements an Interface InterfaceProductEntities,definition of which given just next
- // to the definition of this Class
- class FpProductsEntities :InterfaceProductEntities<FpProduct>
- {
- public List<FpProduct> ListFpProduct { get; set; }
- public List<InterfaceVisitor<FpProduct>> RuleDirectory { get; set; }
- public void AttachRule(InterfaceVisitor<FpProduct> Rule)
- {
- if (RuleDirectory == null)
- RuleDirectory = new List<InterfaceVisitor<FpProduct>>();
- RuleDirectory.Add(Rule);
- }
- public void LoadDate()
- {
- if (ListFpProduct == null)
- {
- ListFpProduct = new List<FpProduct>();
- }
- ListFpProduct.Add(new FpProduct("Prd1", "Loan0Tom2019", "Loan", 2000, 1500, 1));
- ListFpProduct.Add(new FpProduct("Prd2", "Loan0Moody2017", "USLease", 12000, 150, 1));
- ListFpProduct.Add(new FpProduct("Prd3", "Loan0Tom2018", "SLoan", 2000, 1500, 1));
- ListFpProduct.Add(new FpProduct("Prd4", "Loan0Rex2018", "LLoan", 20000, 1500, 1));
- ListFpProduct.Add(new FpProduct("Prd5", "Loan0Ahuja2020", "CarLoan", 9000, 15000, 1));
- ListFpProduct.Add(new FpProduct("Prd6", "Loan0Pat2019", "Loan", 7000, 7500, 1));
- }
- }
- // InterfaceProductEntities
- interface InterfaceProductEntities<T>
- {
- List<T> ListFpProduct { get; set; }
- List<InterfaceVisitor<T>> RuleDirectory { get; set; }
- }
We defined how our entity and collection of entities will look like,now lets see the rules.For now I have added only two rule types.
- ClassVisitValidateField
This rule will compare field value with a constant. For example, a rule of this type will be described: "ProductTotalAmount should be greater than 10000". - ClassVisitCompareFields
This will compare the values of two fields like ProductTotalAmount should be greater than ProductBalanceAmount.
Based upon the criteria set by rules, the result set will be filtered out as output, which we will see later.
These classes are as follows
Join the conversation! Your thoughts help the community grow.