Warm tip: This article is reproduced from stackoverflow.com, please click
c# design-patterns

Validation Logic software Pattern

发布于 2020-04-15 10:36:55

I have Software Products that can be installed on one or more systems (Servers/ Desktops/ Hardwares) Each product has logic on how it keyCode is defined (specification). The logic may be same for many Software Products with little change.

Product-> defined by ProductCode ->required unique keyCode for installation

I need to validate key entered by a user against the keycode validation for that product.

What is a good software pattern for this kind of process

The way I have done so far is

{
    readonly arrayofproductCodes;
    public CanProcess(string productCode)
    {
        return  arrayofproductCodes.contains(productCode);
    }


    public validate(string keyCode)
    {
        return validation result;
    }
}

There could be several 100 Software Products and new ones added every other month.

I feel that there should be some creation pattern to create Instantiate validation logic based on ProductsCode.

Let me know if my quetion is clear.

Regards,

Mar

Questioner
TheMar
Viewed
61
JohanP 2020-02-04 06:45

What you can do is create an interface:

public interface IProductValidator
{
    bool CanProcess(string productCode);
    void Validate(string keyCode);
}

Then implement this interface for every product you want to validate:

public class XYZProductValidator : IProductValidator
{
     public bool CanProcess(string productCode)
     {
         return productCode == "XYZ";
     }

     public void Validate(string keyCode)
     {
         //validation logic
     }
}

If you're using dependency injection, go and register this as a singleton. If you're not using DI, then you need some factory class that will be responsible for the creation of every class.

In your calling code, if you are using DI, you can inject an IEnumerable<IProductValidator> productValidators.

public class Calling
{
    private readonly IEnumerable<IProductValidator> _productValidators;

    public Calling(IEnumerable<IProductValidator> productValidators)
    {
        _productValidators = productValidators;
    }

    public void Validate(string productCode, string keyCode)
    {
        //find the right validator based on productCode
        var validator = _productValidators.Where(v => v.CanProcess(productCode));
        validator.Validate(keyCode);
    }

}

This way in the future when you add more products, all you have to do is implement the IProductValidator interface and all your calling code will just work. Now, if you're worried about looping through and IEnumerable to find the correct IProductValidator, you can have another class e.g. ProductValidatorProvider, inject the IEnumerable<IProductValidator> in there, convert that into a Dictionary<string, IProductValidator> and then use that to find the correct IProductValidator.