I've implemented a rule engine like this:
public interface IRuleEngine
{
List<ValidationMessage> Validate(param1, param2, param3);
}
public class DefaultRuleEngine : IRuleEngine
{
readonly IList<IRule> _rules;
public DefaultRuleEngine()
{
_rules = new List<IRule>()
{
new Rule1(),
new Rule2(),
new Rule3(),
....
};
}
public List<ValidationMessage> Validate(param1, param2, param3)
{
var validationMessageList = new List<ValidationMessage>();
foreach(var rule in _rules)
{
validationMessageList.Add(rule.Validate(param1, param2, param3));
}
return validationMessageList;
}
}
public interface IRule
{
ValidationMessage Validate(param1, param2, param3);
}
public class Rule1 : IRule
{
public ValidationMessage Validate(param1, param2, param3)
{
//do logic, return validation message
return validationMessage;
}
}
Now, this works fine, but maintence has been tedious. I use the rule engine in many places in my code. I've also had to change the parameters it takes in a few times, which has lead to a lot of tedious modifications in all of the different classes where I use it.
I'm starting to think this design isn't that great, and what I can do to change it. What I've been thinking, is instead of passing in each individual param, I create a ValidationParameters class, and just pass that in. This way, when I need to add another parameter - param4 - I don't have to go to each place in the code to made the modification, and can just change the field in the ValidationParameters class. This I don't see being a problem, as not every rule uses each param, so I don't see running into any issues. Like, Rule1 may only use param2 and param3, not param1, for example.
public class ValidationParameters
{
public string Param1 {get;set;}
public string Param2 {get;set;}
public int Param3 {get;set;}
public int Param4 {get;set;}
}
and change the interface to
public interface IRuleEngine
{
List<ValidationMessage> Validate(ValidationParameters);
}
does this look like a good design, or is there a better pattern to use?