Search code examples
c#.netooparchitectureclass-design

Execute Set of ValidationRule-C# Class Design - Better Approach


I have a case there I need to execute set of validation rules for different companies. There will be multiple validation rules against one Company.

So I have following table Structure

Company

ID      CompanyName  
1       ABC   
2       DEF  

ValidationRule

RuleID      Name  
1           Rule1   
2           Rule2 

CompanyValidationRuleMapping

MappingID      CompanyId    RuleID
1              1             1
2              1             2
3              2             2

I have separate stored procedures for every validation rule.

So from my c# code, I will find all validation rule corresponding to a company and need to execute the validation stored procedure associated with that rule.

So I am planning to keep one Interface 'IValidation' which is having different validation methods.

Or

Can i have to create different classes for each validation which implements an interface

Can anyone please suggest a better approach on this.


Solution

  • Your first level of generic validation interface which gives the flexibility of providing both result type and the model to be validated:

    public interface IValidate<T, R>
        where T : class
        where R : class // where T is any custom result and R is your custom model
    {
        T Validate(R model);
    }
    

    Let's say, I need to validate company policies which would be handled by a different sp altogether:

    public interface IValidateCompanyPolicies : IValidate<ValidationResult1, Company>
    {
      ValidationResult1 Validate(Company model);
    }
    

    Again, I also need to check for company monetary accounts, taxes, audits etc:

    public interface IValidateCompanyAccounts : IValidate<ValidationResult2, Company>
    {
      ValidationResult2 Validate(Company model);
      bool HasAuditPassed(Company model);
    }
    

    Resp. classes handling both kinds of IValidate interface

    public class ValidateCompanyPolicies : IValidateCompanyPolicies
    {
        ValidationResult1 Validate(Company model)
        {
            // Hit stored procedure corresponding to company policies validation
        }
    }
    
    public class ValidateCompanyAccounts : IValidateCompanyAccounts
    {
        ValidationResult2 Validate(Company model)
        {
            // Hit stored procedure corresponding to company's monetary accounts validation
        }
    
        bool HasAuditPassed(Company model)
        {
            // Hit stored procedure corresponding to get company audit results
        }
    }
    

    My end class which needs to perform all business intensive operations after performing validation:

    public class XYZCompany
    {
        private IValidateCompanyPolicies companyPoliciesValidation;
    
        private IValidateCompanyAccounts companyAccountsValidation;
    
        public XYZCompany(
            IValidateCompanyPolicies companyPoliciesValidation,
            IValidateCompanyAccounts companyAccountsValidation)
        {
            // Perform DI
        }
    
        public bool UpdateCompany(Company model)
        {
            var checkPolicies = this.companyPoliciesValidation.Validate(model);
    
            if (checkPolicies.Success)
            {
                var checkAccounts = this.companyAccountsValidation.Validate(model);
    
                var auditSuccess = this.companyAccountsValidation.HasAuditPassed(model);
    
                if (checkAccounts.Success && auditSuccess)
                {
                    // Perform DB save
                }
            }
        }
    }