It’s been a while since I blogged, I’ve been busy :)
A requirement I have in an app I am writing is to allow the administrator to set up formulas which can be calculated at runtime. The client app is completely disconnected from Enterprise Core Objects, it uses a (query/command)->response approach so I didn’t want to expose OCL on the client, I also didn’t want to use OCL because I didn’t want arbitrary browsing of the model.
So I have been looking at IronPython – and I like it! I’m not going to go into details of what this code does, I’m just going to paste it so that you may take a look. In short the requirement is for the Admin to be able to retrieve values from the DB by name and perform whatever logic they wish in order to return a decimal result.
You need to reference the following DLLs.
Microsoft.Scripting
Microsoft.Scripting.Core
IronPython
And here is the source example
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using IronPython.Hosting;
using IronPython.Runtime;
using IronPython;
using Microsoft.Scripting.Hosting;
using Microsoft.Scripting;
namespace ConsoleApplication17
{
class ConsoleApplication17
{
[STAThread]
static void Main(string[] rawArgs)
{
var engine = Python.CreateEngine();
var scriptSource = engine.CreateScriptSourceFromString(@"
def foo(paygroup):
global retrievedValue
global factor
retrievedValue = numbers.GetValue(paygroup)
if retrievedValue >= 100000:
factor = 0.75
elif retrievedValue >= 50000:
factor = 0.8
else:
factor = 0.9
return retrievedValue * factor"
, SourceCodeKind.Statements);
//Create a variable which can be used in the script
//to retrieve values from the DB
var scope = engine.CreateScope();
scope.SetVariable("numbers", new Meh());
//Compile the script
scriptSource.Execute(scope);
//Get a reference to the function
Func<string, decimal> foo = scope.GetVariable<Func<string, decimal>>("foo");
//Execute it
Console.WriteLine(foo("a"));
Console.WriteLine(foo("b"));
Console.WriteLine(foo("c"));
Console.ReadLine();
}
}
public interface IMeh
{
int GetValue(string name);
}
public class Meh : IMeh
{
public int GetValue(string name)
{
switch (name)
{
case "a": return 100000;
case "b": return 50000;
default: return 36000;
}
}
}
}