sventevit
sventevit

Reputation: 4816

Convert string to anonymous method

Consider this code:

    static void Main(string[] args)
    {
        var persons = new List<Person>
                          {
                              new Person("Name1", "Surname1", 30),
                              new Person("Name2", "Surname2", 20),
                              new Person("Name3", "Surname3", 10)
                          };

        var filters = new List<Func<Person, bool>>
                          {
                              p => p.Age > 10,
                              p => p.Surname.Contains("2")
                          };

        var personsFiltered = new List<Person>(persons);
        foreach (var filter in filters)
        {
            personsFiltered = personsFiltered.Where(filter).ToList();
        }

        foreach (var person in personsFiltered)
        {
            Console.WriteLine(person);
        }

        Console.ReadKey();
    }
}

class Person
{
    public string Name { get; private set; }
    public string Surname { get; private set; }
    public int Age { get; private set; }

    public Person(string name, string surname, int age)
    {
        Name = name;
        Surname = surname;
        Age = age;
    }

    public override string ToString()
    {
        return String.Format("Name:{0}, Surname:{1}, Age:{2}", Name, Surname, Age);
    }
}

Is it possible to pass filters as string parameters, so that the user could create custom filters? For example, the filters list in my example would initially be empty and the user would provide strings "p => p.Age > 10" and "p => p.Surname.Contains(\"2")"?

Upvotes: 2

Views: 545

Answers (1)

Kevin Coulombe
Kevin Coulombe

Reputation: 1575

You have two options to allow the user to write code for your application : A scripting engine and dynamic compilation.

LUA

You could integrate a scripting engine like Lua (I found that very easy) : /technical/game-programming/using-lua-with-c-r2275">http://www.gamedev.net/page/resources//technical/game-programming/using-lua-with-c-r2275

You need to create a Lua environment, set the variables to be used by the user's script, then read the variables from that environment. I built a partly scripted printing template engine using this method and it worked perfectly. LuaInterface for C# is very intuitive and simple.

DYNAMIC COMPILATION

Another option is to implement dynamic compilation (a little more trouble, but more powerful) : http://www.codeproject.com/KB/dotnet/DynamicCompileAndRun.aspx

You need to create a framework class and concatenate a string to include the user's script inside a class that implements a certain interface. Something like :

class ClientScript : IScriptFramework {
    public override String Method(Object object) {
        return %CLIENT_CODE%;
    }
}

Assuming IScriptFramework declares Method, you can store an isntance of this class into a IScriptFramework and call Method without any reflection. Just store this code in a resource, generate the final source code by replacing %CLIENT_CODE% with the actual code (like object.ToString()) and compiling that in memory as described in the post I linked.

I used dynamic compilation for a testing framework and it works pretty well, although the syntax is more strict than a script engine like Lua.

EDIT : Viacheslav Smityukh is right, there is a framework that does the hard job of dynamically compiling LINQ queries for you. I read about it a while back, but I didn't think about before I saw his comment. It may be the easiest way to go for you : http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

Upvotes: 2

Related Questions