Eval Expression.NET ile Dinamik Kod Derleme

Herkese merhaba, bu makalemde kullanışlı ve bazı durumlarda ihtiyaç duyabileceğiniz bir kütüphane hakkında örnekler paylaşacağım. Konu zaman zaman yapılması gereken ve bizleri uzun kod yığınlarından kurtaran çalışma zamanında (Runtime) kod derleme ve çalıştırma işlemi. Elbette bu işlemin derleme yöntemiyle çalışan programlama dillerinde ödenmesi gereken bazı bedelleri bulunmaktır çünkü bu diller ile yazılan kodlar bir kere derlenir ve Byte Code adı verilen ve her dil için değişen bir başka düşük seviyeli dile çevrilir çalıştırılan ve asıl işi yapan bu kodlardır. Bu kodların arasında üst seviyeli bir dil çalıştırmak için derleme işleminin çalışma zamanında tekrar yapılması gerekir. Bu ise uygulamayı yavaşlatan bir işlemdir fakat yine de kar zarar hesabı yapıldığında bazı durumlarda bu yöntemi kullanabilirsiniz.

C#  programlama dilinde çalışma zamanında kod derleyip çalıştırabilir, executable uygulama ya da dynamic link library (dll) kütüphane olarak dışarıya aktarabilirsiniz. Bu konu için internette pek çok örnek bulunmakta ben bu makalede dinamik derleme işlemi için gerekli işlemleri kısaltıp kullanışlı hale getiren Eval Expression.NET kütüphanesi hakkında bilgi vereceğim. Kütüphane hakkında detaylara buradan ulaşabilirsiniz.

Bu kütüphane aynı zamanda meşhur HtmlAgilityPack kütüphanesinin de geliştiricisi ZZZ Projects tarafından geliştirilmiştir. Anonymous Type, Extension Method, Lambda Expression, LINQ, Method Overloads gibi özellikleri destekyen kütüphane .Net 4 ve üstü versiyonlarında çalışıyor. Aşağıdaki örnekler Visual Studio ortamında Console projesi olarak uygulanmıştır bunun için Nuget Package Manager ile Z.Expressions.Eval kütüphanesini kurarak ya da Package Manager Console editörüne Install-Package Z.Expressions.Eval -Version 2.1.15 yazarak projenize ekleyin.

Eval.Execute

Bir C# ifadesini çalıştırır ve geriye sonuç döndürür. İfade içinde çeşitli şekillerde kullanılacak parametre değerini belirtebilirsiniz:

  • Anonymous Type
  • Argument Position
  • Class Member
  • Dictionary

Sonucunu yazdığınız bir tür olarak döndürebilirsiniz: Method yüklemeleri aşağıdaki gibidir.

  • Eval.Execute<TResult>(string code)
  • Eval.Execute<TResult>(string code, object parameters)
  • Eval.Execute<TResult>(string code, params object[] parameters)
static void Main(string[] args)
{
   // Parameter: Anonymous Type
   int result = Eval.Execute<int>("X + Y", new { X = 1, Y = 2 });
   Console.WriteLine(result);

   // Example 1
   result = Eval.Execute<int>(@"var list = new List<int>() { 1, 2, 3, 4, 5 };
                                var filter = list.Where(x => x < 4);
                                return filter.Sum(x => x);");

   // Parameter: Class Member
   dynamic expandoObject = new ExpandoObject();
   expandoObject.X = 1;
   expandoObject.Y = 2;
   result = Eval.Execute<int>("X + Y", expandoObject);

   // Parameter: Argument Position
   int result = Eval.Execute<int>("{0} + {1}", 1, 2);

   // Parameter: Dictionary Key
   var values = new Dictionary<string, object>() { {"X", 1}, {"Y", 2} };
   int result = Eval.Execute<int>("X + Y", values);

   Console.WriteLine(result);
}

Eval.Compile

Bir C# ifadesini derler ve geriye delegate döndürür. İfade belirteçlere (tokens) ayrıştırılır ve ardından İfade Ağacı (syntax node) kullanılarak derlenmeden önce sözdizimi düğümüne dönüştürülür.

// Delegate Func
var compiled = Eval.Compile<Func<int, int, int>>("{0} + {1}");
int result = compiled(1, 2);

LINQ Dynamic

Listeler üzerinde dinamik sorgu oluşturmanızı sağlar. Karmaşık linq sorgularını bu özellik ile basitleştirebilirsiniz. Dinamik bir C # ifadesi ile herhangi bir sıralama ve seçme yöntemini kullanabilirsiniz:

  • OrderByDescendingDynamic
  • OrderByDynamic
  • SelectDynamic
  • SelectMany
  • ThenByDescendingDynamic
  • ThenByDynamic

LINQ Dinamik deneyimini, Execute yöntemini kullanarak ve başka bir zincirleme yöntemiyle daha ileri götürebilirsiniz:

  • Execute
  • Execute<TResult>
class Program
{
    static void Main(string[] args)
    {
       //Example 1
       var list = new List<int>() { 1, 2, 3, 4, 5 };
       var list2 = list.Where(x => "x > 2").ToList();

       // SelectDynamic
       var list3 = list.SelectDynamic(x => "new { y = x + 1 }");
       var list4 = list.SelectDynamic(x => "new { y = x + 1 }", new { y = 1 });

       // OrderByDynamic
       var list5 = list.OrderByDynamic(x => "x + 1");
       var list6 = list.OrderByDynamic(x => "x + Y", new { Y = 1 });
      
       //Example 2
       var list7 = list.Execute<List<int>>("Where(x => x > 2).OrderBy(x => x).ToList()");          
       Console.Read();
    }
}

Umarım faydalı olmuştur.

Mustafa Tayyip YETİŞ
Yazılım Geliştirme Uzmanı

 

0.0 Ort. (0% puan) - 0 oy

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir