Vítejte na blog.vyvojar.cz Přihlásit | Registrovat | Pomoc

Vlko napísal ...

.. mostly harmless ...
ExpressionEval coding story [Update]

Ako obyčajne začínam hneď zdrojovými kódmi, nech záujemcov o code review nemusím zdržiavať zbytočnými rečmi:)

Zdrojové kódy: http://vlko.zilina.net/dwn/blog/ExpressionEval.zip

Update č. 1

Ospravedlňujem sa, nejak som zverejnil zlú linku, už je to opravené.

Intermezzo

Pretože tu máme vianoce, rád by som vám aj ja dal od ježiška jeden malý darček a tým je knižnica, ktorá z predaného textu a pár ďalších informácii vygeneruje patričnú lambda expression. Síce by som tieto zdrojové kódy zverejnil tak, či tak, ale takto je z toho cítiť krásnu myšlienku. Ten pragmaticky dôvod je ako pri každom oos projekte užívateľský unittesting a možný ďalší rozvoj komunitou, pretože táto malá knižnička narozdiel od ostatných proof of concept coding stories pôjde do production.

Do intermezza tradične patria nejaké tie pohnútky:

  1. V administračnej sekcii sme pre jeden typ problému potrebovali zakomponovať užívateľský filter. V podstate by stačila iba jednoduchá funkčnosť, na základe id urobiť and a or operácie plus vyhodnotenie priorít podľa zátvoriek.
  2. No keď som sa už mal do toho pustiť koncept som troška rozšíril a ďalšia funkčnosť by bol bezpečnostný filter nad DAL entitami, teda aby užívateľ videl len to čo treba.
  3. A pretože by sme radi na komunikáciu server-client použili REST, toto by sa dalo ideálne použiť na serializáciu/deserializáciu Expression, kde by sa po ceste tak nejak stratila typová závislosť, teda na rovnaký Expression pre rôzne triedy s rovnakými properties.

Čo je načrtnuté v bode 2, z bodu 3 je jasne vidieť. Expression je tá správna vec, čo potrebujem, pretože:

  • môžeme ho kompilovať a cachovať v tejto kompilovanej podobe
  • umožnuje používať premenlivé parametre
  • cez linq provider je prevediteľný do sql tvaru
  • a jednoducho sa mi zdá ako praktickejšie riešenie oproti kompilácii z C# kódu [Evaluate C# Code (Eval Function)] alebo čokoľvek iné, čo sa mi podarilo vygoogliť, tak týmto aspoň zatmelím dieru na trhu:)

Kto číta moje správičky na aspnet.sk určite vie, že ma proste takéto veci zaujímaju a keďže som to potreboval do jedného projektu a najmä dostal týždňové pracovné okno, nebolo inej voľby ako sa do toho pustiť. No uznajte pri takýchto úlohach musí človek milovať svoju prácu:)

Ako používať

Po nalinkovaní knižnice stačí vytvoriť inštanciu ExpressionEval, nastaviť jej patričný kód, zaregistrovať patričné parametre, namespaces pre vyhľadávanie typov, niečo ako using v C# a pretože to veru nie je žiaden kompilátor pre získanie typu je potrebné registrovať meno assembly. Vše ukončíte volaním funkcie Eval so špecifikovaním typu delegáta. Všetko pekne vo fluent formáte. A takto nejak to mam v unitteste:

 

        [TestMethod]

        public void SimpleLambda()

        {

            Expression<Func<int, int>> lambda = new ExpressionEval("Convert.ToInt32(String.Concat(\"3\", x.ToString().ToString()))")

                .AddParam<int>("x")

                .AddLookupAssembly("ExpressionEvalTest")

                .AddLookupNamespace("ExpressionEvalTest", "ExpressionEvalTest")

                .Eval<Func<int, int>>();

            int result = lambda.Compile().Invoke(1);

            Assert.AreEqual(31, result);

        }

Síce tie AddLookup funkcie sú tam len kvôli efektu, ale to je teraz nepodstatné, dôležité je vedieť čo podporujeme:

  • statické funkcie, properties a fieldy
  • funkcie, properties a fieldy parametra
  • string reťazce bez obmedzenia, teda viacriadkové a s úvodzovkami definovanými po C#ovsky: \"
  • numerické konštanty okrem toho že číslo s bodkou je desattinný float a bez bodky Int32 je umožnené definovať typy pomocou končiaceho textu, teda (posledné tri som si vymyslel, možno v budúcnosti pridam automatickú konverziu typov):
    • 12.1 - float
    • 12.1f - float
    • 12.1d - double
    • 12 - Int32
    • 12u - UInt32
    • 12l - Int64
    • 12ul - UInt64
    • 12s - Int16
    • 12us - UInt16
    • 12b - Byte
  • indexery
  • operátory (*,/,%,+,-,>,<.<=,>=,==,!=,|,^,&,||,&&, ...)
  • vytváranie inštancii pomocou new keywordu

Ak vás to viac zaujíma, pozrite si priložené unittesty.

Performance

Súčasťou projektu je aj program pre porovnanie výkonnosti. Tá je niekde na úrovni 60 násobku natívne zapísaného lambda výrazu. Poteší aspoň, že evaluácia je predsa len o trošku rýchlejšia ako deserializovanie pomocou MetaLinq.

A coding príbeh?

Pretože sú už dnes vianoce, veľa hodín a online budem až o pár dni, rád by som tento príspevok zverejnil už dnes. Inak by som bol nútený meniť úvod a pokaziť vám tento darček a to by ja nerád. Pre dnes aspoň načrtnem:

  • prvý na rad prichádza tokenizer, čo je jednoduchy regex výraz 

        private const string cTextRegexPart = @"""((?:(?:\\"")|[^""])*)""";

        private const string cExecutableRegexPart = @"(\w+)";

        private const string cDelimiterRegexPart = @"([\(\)\[\]\.,])";

        private const string cOperatorRegexPart = @"([^\w\(\)\[\]\.,\s]+)";

        private const string cCodeParserRegex = cTextRegexPart + "|" + cExecutableRegexPart + "|" + cDelimiterRegexPart + "|" + cOperatorRegexPart;

  • ďalší na rad prichádza stavový automat, ktorý prechádza tokenizovaný text a popritom si vytvára pomocnú tree štruktúru
  • tretím krokom je vygenerovanie expression tree z pomocnej tree štruktúry

TODO

  • ak je záujem tak podrobnejšie rozpísať jednotlivé body, tak dajte vedieť do diskusie
  • dorobiť podporu pre negáciu [!]
Posted: 24. prosince 2008 1:00 by vlko
Vedeno pod: ,

Komentář

morousej napsal:

Knihovna nejde stáhnout - 404 Not Found :( škoda, zrvona by se mi to hodilo

# prosince 29, 2008 17:24

vlko napsal:

Uz som linku opravil, tak ak sa najde problem v buducnosti, staci dat vediet na mail, alebo tu do komentarov.

# prosince 30, 2008 0:00

Vlko napísal ... napsal:

Zdrojové kódy: http://vlko.zilina.net/dwn/blog/ExpressionEval.zip Intermezzo Zaregistrovaním ExpressionEval

# dubna 28, 2009 15:44

Luckie napsal:

Very true! Makes a chnage to see someone spell it out like that. :)

# května 28, 2011 7:36

bppkcv napsal:

# května 28, 2011 10:01

rnsmbavyuk napsal:

TAckf1 , [url=http://okildubbivge.com/]okildubbivge[/url], [link=http://hjcscmzobnzm.com/]hjcscmzobnzm[/link], http://khkbdvqrmdkn.com/

# května 29, 2011 19:29

pxkjtrarxnw napsal:

# května 31, 2011 9:39

erjadvxo napsal:

oD9NVL , [url=http://foznrmzqkbol.com/]foznrmzqkbol[/url], [link=http://yiopdpwqdxit.com/]yiopdpwqdxit[/link], http://vwnrkdbhluch.com/

# června 1, 2011 19:34
Vytvoření nového komentáře

(povinný) 

(povinný) 

(nepovinný)

(povinný) 

Opiš čísla, která vidíš na obrázku:

Upozornění na nové komentáře

Pokud chčeš dostávat upozornění emailem na změny u toho příspěvku,tak se zaregistruj zde.zde

Odebírat komentáře k tomuto příspěvku pomocí RSS

Vyvojar.cz na prodej!