2010-08-09 17 views
2

Si j'avais une liste d'objets par ex. List<Foo>Foo a quelques propriétés, puis-je créer un ou plusieurs scripts ironruby ou ironpython qui s'exécutent pour chaque ligne.Utilisation de IronRuby ou IronPython pour modifier une liste d'objets C#

Voici un code pseudo:

var items = new List<Foo>(); 
foreach(var item in items) { 
    var pythonfunc = getPythonFunc("edititem.py"); 
    item = pythonfunc(item); 
} 

J'ai besoin d'une manière dynamique pour modifier la liste où le code est stocké dans une base ou d'un fichier. Si vous pensez qu'il existe une meilleure façon de le faire, ou avez une alternative pour qu'une routine personnalisée puisse être écrite pour un client qui peut extraire les données spécifiques au client d'une base de données (une exportation), s'il vous plaît commenter ou laissez une suggestion.

Merci

Répondre

4

Je l'ai utilisé cette approche avant, à la fois sauver des scripts IronPython dans une base de données et fichiers. Le modèle que j'aime est de stocker des fonctions Python avec des noms connus par convention. En d'autres termes, si vous traitez un objet de type Foo, vous pouvez avoir une fonction Python nommée "foo_filter" dans votre fichier ou votre table .py. En fin de compte, vous pouvez exécuter un fichier Python et analyser les fonctions dans un dictionnaire de références de fonctions.

Une application rapide de l'échantillon ...

Votre classe foo:

public class Foo { 
    public string Bar { get; set; } 
} 

Mise en place Foo et appelant getPythonFunc (i);

var items = new List<Foo>() { 
    new Foo() { Bar = "connecticut" }, 
    new Foo() { Bar = "new york" }, 
    new Foo() { Bar = "new jersey" }      
}; 

items.ForEach((i) => { getPythonFunc(i); Console.WriteLine(i.Bar); }); 

Une implémentation getPythonFun rapide et sale ... Le graphique de l'objet ScriptXXX doit évidemment être mis en mémoire cache, tout comme les variables récupérées par GetVariable().

static void getPythonFunc(Foo foo) { 

    ScriptRuntimeSetup setup = ScriptRuntimeSetup.ReadConfiguration(); 
    ScriptRuntime runtime = new ScriptRuntime(setup); 
    runtime.LoadAssembly(Assembly.GetExecutingAssembly()); 
    ScriptEngine engine = runtime.GetEngine("IronPython"); 
    ScriptScope scope = engine.CreateScope(); 

    engine.ExecuteFile("filter.py", scope); 

    var filterFunc = scope.GetVariable("filter_item"); 
    scope.Engine.Operations.Invoke(filterFunc, foo); 
} 

Le contenu de filter.py:

def filter_item(item): 
    item.Bar = item.Bar.title() 

Une façon simple d'appliquer des règles fondées sur une propriété (non l'ajout de la propriété Taille Foo):

var items = new List<Foo>() { 
    new Foo() { Bar = "connecticut", Size = "Small" }, 
    new Foo() { Bar = "new york", Size = "Large" }, 
    new Foo() { Bar = "new jersey", Size = "Medium" } 
}; 

Changez la ligne dans getPythonFun() qui appelle GetVariable de ScriptScope():

var filterFunc = scope.GetVariable("filter_" + foo.Size.ToLower()); 

Et le nouveau contenu de filter.py

def filter_small(item): 
    item.Bar = item.Bar.lower() 

def filter_medium(item): 
    item.Bar = item.Bar.title() 

def filter_large(item): 
    item.Bar = item.Bar.upper() 

J'ai un tas d'échantillons plus complets disponibles à http://www.codevoyeur.com/Articles/Tags/ironpython.aspx.

+0

C'est méchant génial! Merci! – Schotime

+0

C'est le moins que je puisse faire pour un contributeur NoRM ... –