Let's say If I have an application which let's user create business rules to be applied on a domain entity. A rule can be a combination of a condition and multiple actions where if condition evaluates to true then corresponding actions are executed. This rule is created by users in free-form text format which is then converted to a proprietary format which rule engine can understand and execute.
E.g. For an employee management system, if there is business rule to check if an employee is working in current Role for more than an year and has performed better than expected then can be promoted to next role with a 10% salary increment. This business rule can be entered by users as below.
Condition: Employee.CurrentRoleLength > 1 && Employee.ExceededExpectations()
Action: Employee.PromoteToNextRole() | Employee.GiveSalaryIncrement(10)
Note that multiple Actions are delimited with a |. Also in order to execute this rule, application uses a separate rule engine class library to parse this condition and both actions to a proprietary format, say, ExecutableScript also defined in the rule engine class library.
Now in order to model this requirement using DDD; I have come up with following Domain objects.
Rule (Entity)
Condition (Value Object)
Action (Value Object)
where Rule is an Entity which contains a Condition Value Object and a list of Action Value Objects as below.
public class Rule : Entity
{
public Condition Condition { get; private set; }
public IList<Action> Actions { get; private set;}
public Rule(Condition condition, IList<Action> actions)
{
Condition = condition;
Actions = actions;
}
}
public sealed class Condition : ValueObject<Condition>
{
public string ConditionText { get; private set;}
public ExecutableScript ExecutableCondition{ get; private set;}
public Condition(string conditionText)
{
ConditionText = conditionText;
}
public Parse()
{
ExecutableCondition = // How to parse using external rule engine ??;
}
public Execute()
{
// How to execute using external rule engine ??;
}
}
public sealed class Action : ValueObject<Action>
{
public string ActionText{ get; private set;}
public ExecutableScript ExecutableAction{ get; private set;}
public Action(string actionText)
{
ActionText = actionText;
}
public Parse()
{
ExecutableAction = // How to parse using external rule engine ??;
}
public Execute()
{
// How to execute using external rule engine ??;
}
}
Based on above domain model, I have following questions.
How can I parse and execute Condition and Actions without having a dependency on external rule engine. I understand Domain layer should not have any dependency on outer layers and should be confined to it's own.
Even if I Parse Condition and Actions outside their domain objects, still their parsed ExceutableScript value need to be present within them which will still need dependency on external rule engine.
Is it just that DDD is not the right approach for this scenario and I am going into wrong direction.
Sorry for the long post. Any help would be highly appreciated.
Thanks.