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ı