پنج شنبه ۷ اردیبهشت ۱۳۹۶
 
 
 
کلمه عبور خود را فراموش کرده اید؟
 

 
 
 C# 5.0 : انقلاب دات نت نزديك است، Compiler as Service - قسمت اول
.NET C#
تاریخ ثبت:  ۹۰/۳/۲۳
تعداد نمایش:  ۸۸۴۱
  نویسنده: ابوالفضل حسن الدين
 
   ۱۷  نفر تا این لحظه به این مقاله امتیاز داده اند.
 
   Bookmark and Share

تاكنون طي سه مقاله در Persia Developers به بحث و بررسي پيرامون ويژگي هاي نسخه بعدي زبان برنامه نويسي سي شارپ دانت نت پرداخته شده است. در مقاله نخست تصويري از آينده ي سي شارپ بر پايه ي اطلاعات كنفرانس هاي مايكروسافت و درخواست هاي توسعه دهندگان سراسر جهان ترسيم شد. پس از كنفرانس PDC 2010 ويژگي ديگري تحت عنوان برنامه نويسي غيرهمزمان مطرح شد كه نسخه بعدي زبان هاي دات نت از آن پشتيباني خواهد كرد. تاكنون دو نسخه پيش نمايشي (CTP) از اين ويژگي توسط مايكروسافت ارائه شده است كه دو مقاله اخير (مقاله اول و مقاله دوم) به بحث و بررسي پيرامون آن پرداخته اند.

مهم ترين ويژگي نسخه بعدي سي شارپ كه بخشي از مقاله نخست با ارائه نمونه كد فرضي به آن اختصاص داده شد، Compiler as Service مي باشد. اين ويژگي به مجموعه اي از API اطلاق مي شود كه به توسعه دهندگان اجازه مي دهد كامپايلر سي شارپ را در زمان اجرا در اختيار داشته باشند! Compiler as Service براي اولين بار در كنفرانس PDC 2008 توسط آندرس هلسبرگ - معمار اصلي و سرپرست تيم طراحي زبان سي شارپ - ارائه شد كه بهت و تحسين حضار را برانگيخت. در كنفرانس PDC 2010، هلسبرگ سعي كرد پيش نمايش ديگري از ويژگي هاي مرتبط با API كامپايلر به نمايش بگذارد كه با بسته شدن ويژوال استوديو هنگام اجراي دمو مواجه شد! تلاش هاي وي براي نمايش اين دمو بي نتيجه ماند و با خنده معنادارش به پايان رسيد. مصاحبه اخير هلسبرگ و سوالاتي كه در اين خصوص مطرح شده اند، حاكي از آنند كه كارهاي زيادي در اين حوزه توسط تيم طراح انجام شده است اما هنوز تاريخي براي ارائه نسخه دمو و آزمايشي ارائه نشده است!



از طرف ديگر تيم طراح كتابخانه Mono كه پروژه آن توسط ناول راه اندازي شده است، نه تنها موفق شد كه نسخه اوليه از اين ويژگي را سال ها قبل ارائه دهد بلكه اينك با پيشتيباني از تمامي نسخه هاي سي شارپ، به توسعه دهندگان اين اجازه را داده است كه برنامه نويسي باورنكردني و انقلابي را در حوزه دات نت تجربه كنند. در اين مقاله براي اولين بار Compiler as Servie با مثال هاي عملي و كاملا اجرايي مورد بحث و بررسي قرار مي گيرد.




 درباره پروژه Mono

پروژه كد باز Mono كه توسط شركت Novell پشتيباني مالي مي شود، بستر لازم براي اجراي اپليكيشن هاي دات نت بر روي پلتفرم هاي غير ويندوزي اعم از يونيكس، لينوكس و مكينتاش را فراهم كرده است. البته اين فريم ورك شامل نسخه قابل اجرا بر روي سيستم هاي عامل ويندوز نيز مي باشد. امكاناتي كه پروژه Mono در اختيار قرار مي دهد، به شرح زير مي باشند:

Mono

عبارت است از پياده سازي كد باز و بين پلتفرمي #C و CLR كه به صورت باينري با دات نت فريم ورك مايكروسافت سازگار مي باشد.
( مطالب بيشتر - دانلود )

MonoDeveloper

محيط كد باز توسعه #C و دات نت براي پلتفرم هاي لينوكس، ويندوز و مكينتاش
( مطالب بيشتر - دانلود )

Mono Tools for Visual Studio

افزونه اي تجاري براي ويژوال استوديو كه امكان تبديل اپليكيشن هاي دات نت براي استفاده بر روي پتلفرم لينوكس را فراهم كرده است.
(مطالب بيشتر)

Moonlight

پياده سازي كد باز سيلورلايت مايكروسافت براي پلتفرم لينوكس و ديگر سيستم هاي عامل مبتني بر Unix/X11
(مطالب بيشتر)

SUSE Linux Enterprise Mono Extension

اجراي تجاري اپليكيشن هاي دات نت از جلمه ASP.NET، ASP.NET AJAX و ASP.NET MVC بر روي سرور SUSE لينوكس را فراهم مي كند.
(مطالب بيشتر)

MonoTouch

توليد اپليكيشن #C و دات نت براي iPhone و iPod Touch با بهره گيري از API آيفون، كدهاي موجود در دات نت، كتابخانه ها و مهارت هاي موجود توسط اين كتابخانه امكانپذير مي باشد.
(مطالب بيشتر)


Mono و Compiler as Service

يكي از پروژه هاي فريم ورك Mono، كامپايلر سي شارپ آن مي باشد كه سرويس هاي لازم براي كامپايل زمان اجراي كدها را فراهم مي كند. اگر به صفحه اين پروژه مراجعه كنيد، خواهيد ديد كه كامپايلر سي شارپ Mono از تمامي نسخه هاي زبان برنامه نويسي سي شارپ پشتيباني مي كند كه عبارتند از:

نسخه 2.0
نسخه 3.0
  • Extension methods
  • Query expressions (LINQ)
  • Expression trees
  • Automatically implemented properties
  • Lambda expressions
  • Anonymous types
  • Collection initializers
  • Object initializers
  • Implicitly typed arrays
  • Partial methods
نسخه 4.0
  • Dynamic binding support
  • Generic type variance
  • Optional parameters
  • Named arguments
اين ويژگي در قالب يك كلاس تحت عنوان Evaluator ارائه شده است. Evaluator با دريافت كد سي شارپ امكان كامپايل و اجراي آن را به سادگي هر چه تمام فراهم مي كند!

براي بررسي بيشتر به مثال هايي كه در ادامه ارائه مي شوند، توجه كنيد.


اولين تجربه برنامه نويسي با سرويس كامپايلر سي شارپ

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Mono.CSharp; 
   
namespace PdMonoCompilerServiceSamples
    class Program 
    
        static void Main(string[] args) 
        
            //مقداردهي اوليه سرويس
            Evaluator.Init(new string[0]); 
   
            //در ادامه، سرويس، براي كامپايل و اجراي چند خط كد به شكل زير مورد استفاده قرار مي گيرد
   
            // افزودن فضاهاي نام لازم
            Evaluator.Run("using System;"); 
            Evaluator.Run("using System.Linq;"); 
            Evaluator.Run("using System.Collections.Generic;"); 
   
            // مجموع ارقام ليست محاسبه و نمايش داده مي شود
            Evaluator.Run("List<int> numbers= new List<int> {1,2,4,3} ;"); 
            Evaluator.Run("var sum=0; foreach(var num in numbers) sum+=num;"); 
            Evaluator.Run("Console.WriteLine(sum);");       
        
    
}

حاصل اين اجرا عدد 10 بوده كه در كنسول نمايش داده مي شود!

كلاس Evaluator دو تابع اصلي براي اجراي كد فراهم مي كند:
  • Run : اجراي كد توسط اين تابع شامل مقدار بازگشتي نمي باشد.
  • Evaluate : اين تابع كد ورودي را پردازش كرده و خروجي حاصل از كد را برمي گرداند.
براي درك عملكرد Evaluate به مثال زير توجه كنيد:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mono.CSharp;
    
namespace PdMonoCompilerServiceSamples
{
    // كلاس كمكي شامل دو تابع بسط داده شده
    // كه اجراي كدها را ساده تر و رساتر كنند
    public static class EvaluatorExtensions
    {
        public static T Eval<T>(this string code) where T : class
        {
            // خروجي حاصل از اجراي كد به نوع تي
            //  تبديل و برگردانده مي شود
            return Evaluator.Evaluate(code) as T;
        }
            
        public static void Run(this string code)
        {           
            Evaluator.Run(run);
        }
    }
    
    //برنامه اصلي
    class Program
    {
        static void Main(string[] args)
        {
            //مقداردهي اوليه به سرويس
            Evaluator.Init(new string[0]);
    
            //معرفي فضاهاي نام و اجراي كد با
            //استفاده از تابع بسط داده شده
            "using System;"+
            "using System.Linq;"+
            "using System.Collections.Generic;".Run();
    
            // تعريف ليستي از اعداد صحيح
            List<int> numbers = new List<int> { 1, 30, 90, 23, 46, 22, 50 };
    
            //تعريف تابع مقايسه به صورت پويا
            var match="new Predicate<int>(num=> num>20 && num <44);".Eval<Predicate<int>>();
            // استفاده از تابع به دست آمده از كامپايل
            var filtered = numbers.FindAll(match);
            // چاپ خروجي حاصل از اجرا
            filtered.ForEach(n => Console.WriteLine(n));
        }
    }
}

خروجي حاصل از اين اجرا به صورت زير خواهد بود:

30
23
22

به خط كدي كه با رنگ پس زمينه مشخص شده است توجه كنيد. اين خط كد انقلابي در برنامه نويسي دات نت به شمار مي رود. چرا كه يك رشته (string) توسط سرويس كامپايلر كامپايل شده، و يك تابع از نوع Predicate به دست مي آيد كه در ادامه اجراي برنامه فراخواني شده و مورد استفاده قرار مي گيرد! به همين راحتي به همين سادگي!


كنسول اجرايي هلسبرگ

دمويي كه هلسبرگ در كنفرانس PDC 2008 ارائه داد، شامل يك كنسول بود كه با دريافت كد از خط فرمان، مستقيما آنرا اجرا مي كرد. حاصل اين اجرا نيز در پنجره كنسول نمايش داده مي شد. اينك مي توان با چند خط كد زير به سادگي هر چه تمام اين دمو را شبيه سازي كرد:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using Mono.CSharp; 
   
namespace MonoCompilerHost 
    class Program 
    
        static void Main(string[] args) 
        
            Console.WriteLine(">Mini Console\n\n"); 
            while (true)  
            
                Console.Write(">");  
                string input = Console.ReadLine(); 
                if (input == "@@") return
                Evaluator.Run(input); 
            
        
    
}

در صورت اجراي اين مثال مي توان به شكل زير كدها را مستقيما از خط فرمان اجرا كرد(!):




آخرين نسخه سرويس كامپايلر سي شارپ

مثال هايي كه تاكنون در اين مقاله ارائه شده اند، همگي بر مبناي نسخه ي قبلي كامپايلر سي شارپ نوشته شده اند. طي بروزرساني كه چند ماه پيش توسط تيم Mono انجام شد، قابليت هاي جديد و كارآمدي به كامپايلر سي شارپ اضافه شده اند. از جمله مهم ترين اين نوآوري ها مي توان به امكان نمونه سازي (ايجاد Instance) از كلاس Evaluator اشاره كرد (كه قبلا حالت استاتيك داشته است). به اين ترتيب محدوديتي در ايجاد انواع مفسرها كه بتوان كدهاي جداگانه اي را توسط آنها كامپايل كرد، وجود ندارد. در ضمن هر نوع ساختار كد در حوزه سي شارپ (شامل كلاس ها، توابع و حتي عبارات) را مي توان توسط سرويس جديد، كامپايل و اجرا كرد.

مثال بعدي، جديدترين نسخه سرويس كامپايلر Mono را در عمل نشان مي دهد:

using System;
using Mono.CSharp;
 
 
namespace PdMonoCompilerServiceSamples
{
    class Program
    {
        public static void Main(string[] args)
        {
            // خروجي سرويس كامپايلر از نوع كنسول خواهد بود
            var report = new Report(new ConsoleReportPrinter());
            // تعريف پارسر
            var commandLineParser = new CommandLineParser(report);
            // دريافت تنظيمات از خط فرمان در صورت وجود
            var settings = commandLineParser.ParseArguments(args);
            if (settings == null || report.Errors > 0)
                Environment.Exit(1);
            // ايجاد يك نمونه از سرويس كامپايلر با آرگومان ها
            var evaluator = new Evaluator(settings, report);
            // اضافه كردن  فضاي نام لازم
            evaluator.Run("using System;");
            // تعريف يك نوع جديد
            evaluator.Run(@"class PdDynamicType
                              {
                                public static void DynamicPrint(dynamic statement)
                                {
                                    Console.WriteLine(statement);
                                }
                               }");
            // در اختيار گرفتن نوع تعريف شده از طريق اكشن
            var action = (Action<dynamic>)evaluator.Evaluate("new Action<dynamic>(PdDynamicType.DynamicPrint);");
            // فراخواني تابع با مقدار دلخواد
            action("By Abolfazl Hosnoddinov : First 'Compiler as Service' Test!!! Oh my...");
            Console.ReadLine();
        }
    
}

علاوه بر تغييراتي كه در نحوه نمونه سازي كلاس Evaluator ايجاد شده است، به نوع dynamic اكشن دقت كنيد. اين نكته كه سرويس كامپايلر Mono از آخرين نسخه سي شارپ به خوبي پشتيباني مي كند بسيار حائز اهميت مي باشد (اين در حاليست كه مايكروسافت تاكنون حتي يك دمو هم ارائه نداده است!)

كلاس Evaluator دو تابع زير را براي افزودن اسمبلي هاي بيشتر به حوزه كامپايل ارائه مي دهد:
  • LoadAssembly : اين تابع مسير فايل اسمبلي را براي افزودن آن به عنوان يك مرجع به سرويس كاميايلر دريافت مي كند.
  • ReferenceAssembly : اين تابع نيز با دريافت Assembly، آنرا به فهرست مراجع سرويس كامپايلر اضافه مي كند.
مثال زير به عنوان آخرين مثال بررسي سرويس كامپايلر Mono ارائه مي شود:

using System;
using System.Reflection;
using Mono.CSharp;
 
namespace PdMonoCompilerServiceSamples
{
    public class Program
    {
        public static void Main(string[] args)
        {
            // خروجي سرويس كامپايلر از نوع كنسول خواهد بود
            var report = new Report(new ConsoleReportPrinter());
            // تعريف پارسر
            var commandLineParser = new CommandLineParser(report);
            // دريافت تنظيمات از خط فرمان در صورت وجود
            var settings = commandLineParser.ParseArguments(args);
            if (settings == null || report.Errors > 0)
                Environment.Exit(1);
            // ايجاد يك نمونه از سرويس كامپايلر با آرگومان ها
            var evaluator = new Evaluator(settings, report);
            // اضافه كردن اسمبلي اجرايي به عنوان مرجع سرويس كامپايلر
            evaluator.ReferenceAssembly(Assembly.GetExecutingAssembly());
            // فراخواني تابع از اسمبلي در حال اجرا
            evaluator.Run("PdMonoCompilerServiceSamples.Program.PdFunc();");
            Console.ReadLine();
        }
 
        public static void PdFunc()
        {
            Console.WriteLine("Yes...That's It! Thanks for Mono Team :)");
        }
    
}

به اين ترتيب تابع PdFunc از اسمبلي در حال اجرا فراخواني شده و عبارت بالا را در كنسول چاپ مي كند!

منابع براي مطالعه بيشتر

اگر سوالاتي در رابطه با سرويس كامپايلر Mono داريد و يا مي خواهيد از جزئيات بيشتري مطلع شويد، مطالعه لينك هاي زير پيشنهاد مي شود:

دانلود


كنسول سرويس كامپايلر
فريم ورك Mono


كلام آخر

بدون شك سرويس كامپايلر قوي ترين و جالب ترين ويژگي ست كه تاكنون در حوزه دات نت و شايد ديگر زبان هاي برنامه نويسي ارائه شده است. هيچ محدوديتي براي استفاده از آن نمي توان متصور شد و ارائه نهايي اين ويژگي روند برنامه نويسي را تغيير خواهد داد. برنامه نويسي پويا و زمان اجرا بيشتر و بيشتر مورد توجه قرار خواهد گرفت.

تيم Mono اين موفقيت بزرگ خود را با اين جمله عنوان كرد:

.The Mono team is proud to bring you a preview of C# 5.0 a few years before our friends in Building 41 do

و با اين جمله نيز آن را به پايان برد:

!Our compiler is MIT X11 licensed, so even developers at Microsoft can download this code and look at it. It is all kosher guys

بايد منتظر ماند و ديد مايكروسافت چگونه اين ويژگي را ارائه خواهد كرد. بدون شك حرفاي زيادي هم براي گفتن خواهد داشت. مقاله بعدي از اين سري، به بررسي سرويس كامپايلر مايكروسافت (پس از ارائه شدن آن) اختصاص خواهد يافت.
از همراهان گرامي، همكاران عزيز و خوانندگان ارجمند وب سايت، خواهشمند است ما را از نكته نظرات و پيشنهادات خود بهره مند سازند. همراهي و استقبال شما، مشوق گرمي براي ارائه مقالات بعدي خواهد بود.




(هر گونه استفاده از مقالات اختصاصي PersiaDevelopers در صورت درج منبع و نام نويسنده بلامانع مي باشد.)

فایل ضمیمه مقاله: PdMonoCompilerServiceSamples.rar
  کیفیت مقاله ارائه شده از نظر شما   
برای دادن رتبه به این مقاله می بایست Login کرده باشید.
  درباره نویسنده
ابوالفضل حسن الدين
On my own in the programming world
همه مقاله های نوشته شده توسط این کاربر (۲۵)
 
  پیام جدید
صفحه ۱ - پیامهای اصلی ۱ تا ۱۰ از مجموع ۱۰ پیام اصلی
اولین قبلی بعدی

 عنوان فرستنده تاریخ
 
فقط #C یا در کل NET. صالح باقري ۱۳۹۰/۴/۲۶
پاسخ به: فقط #C یا در کل NET. ابوالفضل حسن الدين ۱۳۹۰/۴/۲۷
پاسخ به: فقط #C یا در کل NET. صالح باقري ۱۳۹۰/۴/۲۸
 
مرسی امییرضا مقسمی ۱۳۹۰/۳/۲۹
پاسخ به: مرسی ابوالفضل حسن الدين ۱۳۹۰/۳/۳۰
 
خیلی خوب بود مرسی کاوش حسینی ۱۳۹۰/۳/۲۹
پاسخ به: خیلی خوب بود مرسی ابوالفضل حسن الدين ۱۳۹۰/۳/۳۰
 
لذت برديم سيد امين منعميان ۱۳۹۰/۳/۲۹
پاسخ به: لذت برديم ابوالفضل حسن الدين ۱۳۹۰/۳/۲۹
 
ایده ی جدید رو دوست می داریم :دی مصطفی چلیک ۱۳۹۰/۳/۲۵
پاسخ به: ایده ی جدید رو دوست می داریم :دی ابوالفضل حسن الدين ۱۳۹۰/۳/۲۵
 
ریسک استفاده از Mono مرتضی صحراگرد ۱۳۹۰/۳/۲۵
پاسخ به: ریسک استفاده از Mono ابوالفضل حسن الدين ۱۳۹۰/۳/۲۵
 
اهمیت سرویس کامپایلر مجید شهاب فر ۱۳۹۰/۳/۲۵
پاسخ به: اهمیت سرویس کامپایلر ابوالفضل حسن الدين ۱۳۹۰/۳/۲۵
 
شما در سي شارپ 3 هم به توانايي‌هاي كامپايلر دسترسي داريد سعيد خان ۱۳۹۰/۳/۲۴
پاسخ به: شما در سي شارپ 3 هم به توانايي‌هاي كامپايلر دسترسي داريد ابوالفضل حسن الدين ۱۳۹۰/۳/۲۴
پاسخ به: شما در سي شارپ 3 هم به توانايي‌هاي كامپايلر دسترسي داريد سعيد خان ۱۳۹۰/۳/۲۴
پاسخ به: شما در سي شارپ 3 هم به توانايي‌هاي كامپايلر دسترسي داريد ابوالفضل حسن الدين ۱۳۹۰/۳/۲۵
 
Mono و سیاست های مایکروسافت فربد صالحی ۱۳۹۰/۳/۲۳
پاسخ به: Mono و سیاست های مایکروسافت ابوالفضل حسن الدين ۱۳۹۰/۳/۲۴
 
آينده Mono در هاله اي از ابهام! اميدواريم توسعه اين پروژه بي نظير و عالي ادامه پيدا كند ابوالفضل حسن الدين ۱۳۹۰/۳/۲۳
پاسخ به: آينده Mono در هاله اي از ابهام! اميدواريم توسعه اين پروژه بي نظير و عالي ادامه پيدا كند سعيد خان ۱۳۹۰/۳/۲۴
پاسخ به: آينده Mono در هاله اي از ابهام! اميدواريم توسعه اين پروژه بي نظير و عالي ادامه پيدا كند ابوالفضل حسن الدين ۱۳۹۰/۳/۲۴
اولین قبلی بعدی

Copyright © 2006 - 2016 All Rights Reserved.
Please direct your questions or comments to