Best Approach to do this with Flee 0.9.13

Nov 30, 2007 at 12:51 PM
Hi, im going to reimplement what i was doing with this release, i try to explain so you can tell me how to approach a solution:

Simplifying my case, end users creates document with are templates with "bookmarks" for example:

  • Mr <FullName>. *

  • We tell you must pay the amount of <Debt> before the day of <LimitDay> .... *

So when they emit this document for a customer, the bookmarks should be resolved for the customer and replaced by customer properties, this example is trivial and in general there is no direct property to resolve a bookmark, instead the user makes an expression and i (flee) must resolve the expresion to replace the bookmark, in general to resolve all bookmarks users generate partial expressions and nested expressions, for example first make an expresion for the tax rate to a date, the this tax rate is used to calculate the debt, then according to ranges of the debt they put some message or other, etc.

So when flee comes to action i have a bunch of expressions (name, expression) like:

"FullName" --> "Customer.FirstName + ' ' + Customer.LastName"
"TaxRate" --> "Financial.CalculateTax( Customer.DebtDate )"
"Debt" --> "TaxRate * Customer.OriginalDebt"

And a Customer object (must be resolved as "Customer" of the expressions)
Also some environment objects like "Financial"

Ok, i think this is the general idea, flee must resolve the expressions, give me a result Object for each expression and i finally replace the bookmarks for the result objects.

Can you point me on how to use the calculation engine and flee in general to acomplish this ?

Many Thanks...
Dec 4, 2007 at 2:26 AM
Sorry for the delayed response. I'll look it over and give you a reply tomorrow or wednesday.
Dec 4, 2007 at 10:36 AM
ok, no problem below is how i doing it now, Concept are the class wich contains the expression to evaluate and a name to nested references. I dont know how to format source code in codeplex editor so if the code doesnt read well copy to a C# editor.

Im sure that the contex and the variables are going to a private procedure and be parametrized in short, please tellme if im doing something wrong or can do better.

----- Here starts C# code -----

public IDictionary<Concept, Object> Solve(IList<Concept> concepts)

solvedConcepts = new Dictionary<Concept, Object>();

CalculationEngine engine = new CalculationEngine();
ExpressionContext context = new ExpressionContext();

context.CalculationEngine = engine;

Customer customer = BaseFactory.Instance.InstanceOfCustomer(keyOfCustomer);

context.Imports.ImportStaticMembers(typeof(Environment), "Env");

context.Variables.DefineVariable("Customer", typeof(Customer));
context.Variables.SetVariableValue("Customer", customer);

context.Options.Checked = true;

foreach (Concept concept in concepts)
if (logger.IsDebugEnabled)
logger.Debug("Evaluating concept: " + concept.ToString());
logger.Debug("Expression: (" + concept.Name + ") -> " + concept.Expression);

context.ExpressionName = concept.Name;
ExpressionFactory.CreateDynamic(concept.Expression, context);


Object result = engine.GetResult(concept.Name);

if (logger.IsDebugEnabled)
logger.Debug("Result: " + result.ToString());

solvedConcepts.Add(concept, result);


return solvedConcepts;

Dec 6, 2007 at 1:03 AM
Everything in your code looks right. You can remove the engine.Recalculate(concept.Name); line as a recalculate is automatically performed when an expression is added to the calculation engine.

The only problem I can see is that currently, you have to add concepts in a specific order (add a concept after all concepts it depends on) into the calculation engine. I'm planning on fixing this when I refactor the calculation engine in the next release so you may want to wait until that happens.
Dec 6, 2007 at 11:22 AM
OK, yes it be a safe if this feature is added.

Jan 13, 2008 at 1:20 AM
Have a look at the sample project attached to the calculation example page. It shows how to use Flee- to implement a simple templating system.