Используя установить IronPython или IronRuby, чтобы изменить список объектов c#


Если бы у меня был список объектов, например. List<Foo> где Foo имеет несколько свойств, я мог бы затем создать один или несколько сценариев ironruby или ironpython, которые работают для каждой строки.

Вот какой-то псевдокод:

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

Мне нужен динамический способ изменения списка, в котором код хранится в БД или файле.

Если вы считаете, что есть лучший способ сделать это, или есть альтернатива, так что пользовательская процедура может быть написана для клиента, который может извлечь данные конкретного клиента из база данных (экспорт), пожалуйста, прокомментируйте или оставьте свое предложение.

Спасибо

1 2

1 ответ:

Я уже использовал этот подход раньше, сохраняя скрипты IronPython как в базе данных, так и в файлах. Мне нравится хранить функции Python с именами, известными по соглашению. Другими словами, если вы обрабатываете объект типа Foo, у вас может быть функция Python с именем "foo_filter" в вашем файле .py или таблице. В конечном счете, вы можете выполнить файл Python и проанализировать функции в словаре ссылок на функции.

Быстрый пример приложения...

Ваш фу класс:

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

Настройка Foo и вызов 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); });

Быстрая и грязная реализация getPythonFun... Очевидно, что граф объектов ScriptXXX должен быть кэширован, как и переменные, полученные с помощью 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);
}

Содержание filter.py:

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

Простой способ применения правил, основанных на свойстве (не добавление свойства размера на 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" }
};

Измените строку в getPythonFun (), которая вызывает ScriptScope GetVariable ():

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

И новое содержание 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()

У меня есть куча более полных образцов, доступных в http://www.codevoyeur.com/Articles/Tags/ironpython.aspx .