Hi,
I'm trying to extend the code sample from Ayende described on
http://ayende.com/Blog/archive/2007/12/11/A-rule-engine-in-less-than-70-lines-of-code.aspx.
When you use a statement in the when clause I want to check first if
the properties used in the conditions are not null.
See code sample:
public abstract class Rule
{
public delegate bool Condition();
public delegate void Action();
public delegate object Value();
protected OrderedDictionary conditionsAndActions = new
OrderedDictionary();
protected System.Collections.Generic.List<Value> constraints =
new System.Collections.Generic.List<Value>();
public object User{ get; set;}
public object Car{ get; set;}
[Meta]
public static Expression when(Expression expression,
Expression action)
{
System.Collections.Generic.List<MemberReferenceExpression>
conditions = new
System.Collections.Generic.List<MemberReferenceExpression>();
ParseNotNullConstraints(expression,conditions);
var totalExpression = new BlockExpression();
foreach (var constraint in conditions)
{
var notnullcondition = new BlockExpression();
notnullcondition.Body.Add(new ReturnStatement
(constraint));
totalExpression.Body.Add(new MethodInvocationExpression
(new ReferenceExpression("NotNull"),notnullcondition));
}
var condition = new BlockExpression();
condition.Body.Add(new ReturnStatement(expression));
var whenexpression = new MethodInvocationExpression(
new ReferenceExpression("When"), condition, action
);
totalExpression.Body.Add(whenexpression);
return totalExpression;
}
private static void ParseNotNullConstraints(Expression
expression, System.Collections.Generic.List<MemberReferenceExpression>
conditions)
{
if(expression is BinaryExpression)
{
var bexpr = (BinaryExpression) expression;
ParseNotNullConstraints(bexpr.Left,conditions);
ParseNotNullConstraints(bexpr.Right,conditions);
}
if(expression is UnaryExpression)
{
var uexp = (UnaryExpression) expression;
ParseNotNullConstraints(uexp.Operand,conditions);
}
if(expression is MemberReferenceExpression)
{
var type = expression.GetType();
conditions.Add((MemberReferenceExpression)expression);
Console.WriteLine(expression.ToString());
}
}
protected void When(Condition condition, Action action)
{
conditionsAndActions[condition] = action;
}
protected void NotNull(Value checkObject)
{
constraints.Add(checkObject);
}
protected void allow()
{
Console.WriteLine("Accepted");
}
protected void deny()
{
Console.WriteLine("Deny");
}
public abstract void Prepare();
public void Execute()
{
foreach (DictionaryEntry entry in conditionsAndActions)
{
Condition condition = (Condition) entry.Key;
if(condition())
{
Action action = (Action) entry.Value;
action();
break;
}
}
}
public void CheckConstraints()
{
foreach (var value in constraints)
{
if(value()==null)
{
Console.WriteLine("something is null");
}
}
}
}
When I try to use the DSL I get a Boo.Lang.Compiler.CompilerError
exception with the following message:
BCE0034: Boo.Lang.Compiler.CompilerError: Expressions in statements
must only be executed for their side-effects.\r\nD:\\testScript.boo
Can't I use a BlockExpression to invoke multiple method calls? Is
there an other way for doing this?
Thanks in advance,
Bavo
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Rhino Tools Dev" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/rhino-tools-dev?hl=en
-~----------~----~----~----~------~----~------~--~---