قبل از اینکه مقاله رو شروع کنم، شما میتوانید نسخه ویدیویی کامل این مقاله را در این لینک مشاهده کنید.
فهرست موضوعی این مقاله:
- Base Class Library (BCL)،
- Common Language Runtime (CLR)
- Common Intermediate Language (CIL)
- .NET assembly
قبل از آنکه بخواهم در مورد فهرست فوق صحبت کنم، بیایید نگاهی اجمالی به Framework Class Library (FCL) بیندازیم که در آن میتوانید بسیاری از کلاسها، عملکردها و سایر خدمات را ببینید.
بررسی CLR (Common Language Runtime)
از دید یک برنامه نویس، دات نت می تواند یک محیط زمان اجرا (runtime) و یک کتابخانه کلاس پایه جامع (base class library) باشد.
زمان اجرا به زمان اجرای زبان مشترک (CLR) اشاره میکند. هدف اصلی CLR بارگذاری، مکان یابی و مدیریت اشیاء دات نت از طرف برنامه نویس است. این بدان معناست که CLR همیشه این عملیات را در پس زمینه انجام می دهد و برنامه نویس در این فرآیندها مداخله ای ندارد.
همچنین، CLR از مدیریت حافظه، میزبانی برنامه، برخی بررسی های امنیتی و هماهنگی thread ها مراقبت می کند.
بررسی CTS (Common Type System)
میتوان گفت CTS تمام انواع داده ها و تمام ساختارهای مرتبط پشتیبانی شده توسط زمان اجرا را توصیف می کند، جزئیات نحوه نمایش آنها در فرمت دات نت متادیتا را توضیح می دهد و همچنین نحوه تعامل entity با یکدیگر را مشخص می کند. به عبارت دیگر، ما چندین زبان برنامه نویسی داریم و هر زبانی تعریف نوع داده ای خاص خود را دارد و برای زبان های دیگر قابل درک نیست، اما CLR می تواند تمام انواع داده ها را درک و به یک الگوی مشترک تبدیل کند.
به عنوان مثال، سی شارپ دارای نوع داده int و VB.NET دارای نوع داده integer است. بنابراین پس از کامپایل، این نوع داده ها به ساختار Int32 در CTS تبدیل می شود.
بررسی CLS (Common Language Specification)
باید گفت CLS زیرمجموعهای از CTS است، مجموعهای از قوانین و محدودیتهایی را تعریف میکند که هر زبان باید از آنها پیروی کند که تحت چارچوبNET. قابل اجرا هستند.
به عنوان مثال تصور کنید برنامه ای را با #C و دیگری را با VB.NET توسعه دهید، در سی شارپ هر عبارت باید با یک نقطه ویرگول خاتمه یابد،, ولی در VB.NET انتهای کد شما به این شکل نیست.
بنابراین این قواعد از زبانی به زبان دیگر متفاوت است اما CLR می تواند syntax تمام زبان ها را درک کند زیرا در دات نت هر زبان پس از کامپایل به کد MSIL تبدیل می شود و کد MSIL مشخصات زبان CLR است.
بررسی Base Class Library (BCL)
مخفف Base class library که با نام Class Library (CL) نیز شناخته می شود. BCL زیرمجموعه ای از کتابخانه کلاس Framework (FCL) است. Class library مجموعه ای از کتابخانه های قابل استفاده مجدد است که با CLR ادغام شده اند. کتابخانه کلاس پایه، کلاس ها و typeهایی را ارائه می دهد که در انجام عملیات روزانه مفید هستند، به عنوان مثال. سر و کار با رشته ها، انواع primitive ها ، اتصال پایگاه داده و عملیات IO.
این کتابخانه نوعی را تعریف می کند که می توان از آنها برای ساخت هر نوع نرم افزاری استفاده کرد.
شما می توانید از ASP.NET برای توسعه وب سایت ها، از REST برای ساخت سیستم های توزیع شده و از WPF برای ساخت برنامه های رابط کاربری گرافیکی دسکتاپ و غیره استفاده کنید. همچنین، کتابخانه های کلاس پایه انواعی را برای تعامل با دایرکتوری و سیستم فایل در یک کامپیوتر را تعیین میکند و ارتباط با پایگاه های داده رابطه ای (از طریق ADO.NET) و غیرهرا نیز ارائه می دهد.
بررسی Managed and Unmanaged Code
اکنون که با تعریف BCL و CLR آشنا شدید، در مورد کدهای مدیریت شده (managed code) و مدیریت نشده (unmanaged code) صحبت خواهم کرد.
کدهایی که توسط خود runtime در زبان برنامه نویسی #C و... نوشته میوشند و توسط CLR قابل درک هستند را کدهای مدیریت شده میگویند، اما به کدهایی که خارج از Runtime توسعه داده شده اند را کدهای مدیریت نشده میگویند.
همانطور که اشاره کردم، پلت فرم دات نت می تواند بر روی انواع سیستم عامل ها اجرا شود. می توان یک برنامه #C را بر روی سیستم عامل ویندوز با استفاده از ویژوال استودیو توسعه داد و برنامه را بر روی یک ماشین macOS اجرا کرد. همچنین می توانید با استفاده از Xamarin Studio یک اپلیکیشن سی شارپ بر روی سیستم عامل لینوکس بسازید و برنامه را روی ویندوز، macOS و ... اجرا کنید.
صرف نظر از اینکه کدام زبان دات نت را برای توسعه انتخاب کرده اید، پس از کامپایل برنامه شما دو نوع اسمبلی وجود خواهد داشت، Executing files *.exe و Dynamic Link Library *.dll.
اما وقتی برنامه دات نت خود را کامپایل می کنیم، به کد باینری اجرایی تبدیل نمی شود، بلکه به یک کد میانی به نام MSIL یا IL تبدیل می شود که با CLR قابل درک است. MSIL یک کد مستقل از سیستم عامل و H/W است. زمانی که برنامه باید اجرا شود، این کد MSIL یا میانی به کد اجرایی باینری تبدیل می شود که به آن کد بومی می گویند.
همه مجموعههای داتنت شامل تعریف انواع، اطلاعات نسخهسازی برای نوع متا داده و مانیفست هستند و در این مقاله قصد دارم بیشتر در مورد آن صحبت کنم.
اگر کلاسی به نام Customer دارید، نوع متادیتا جزئیاتی مانند کلاس پایه مشتری را توصیف میکند، مشخص میکند کدام رابطها توسط کلاس مشتری پیادهسازی میشوند، و همچنین اطلاعاتی درباره هر عضو در کلاس مشتری ارائه میدهد.
کتابخانه CIL و متادیتای Type، خود نیز با استفاده از metadata توصیف میشوند که manifestنامیده میشود. manifestحاوی اطلاعاتی در مورد نسخه فعلی اسمبلی و لیستی از همه مجموعههای ارجاع شده خارجی است که برای اجرای صحیح برنامه لازم هستند. بنابراین در مقاله زیر، من قصد دارم از ابزاری برای بررسی نوع، metadata و manifest یک اسمبلی استفاده کنم.
برای درک CIL به کد سی شارپ زیر که یک ماشین حساب را مدل می کند نگاهی بیندازید.
using System; namespace Calculator { class Program { static void Main(string[] args) { Calc cl=new Calc(); Console.WriteLine("13+31={0}",cl.AddNumbers(13,31)); Console.ReadLine(); } } //Calculator class which has a method Addnumbers class Calc { public int AddNumbers(int x, int y) { return x + y; } } }
همانطور که می بینید ما دو کلاس داریم:
پس از کامپایل کردن برنامه با استفاده از کامپایلر C# (Calculator.exe)، در نهایت یک فایل *.exe که حاوی یک manifest ، metadata و دستورالعمل های CIL است را مشاهده خواهید کرد.
حالا بیایید از ildasm.exe برای بررسی فایل Calculator.exe خود استفاده کنیم.
سه چیز اساسی را به شما نشان خواهد داد:
برای باز کردن اسمبلی مربوطه فقط به منوی tools بروید، ILDASM در این منو ظاهر می شود و شما میتوانید آن را باز کنید.
بنابراین، اگر میخواهید اطلاعاتی درباره برنامه خود پیدا کنید، ildasm را در منوی Tools باز کنید و کادر گفتگوی ildasm.exe را مشاهده خواهید کرد.
همانطور که می بینید اطلاعاتی در مورد نوع اسمبلی، مانیفست و ابرداده وجود دارد.
اگر Calculator.Calc را باز کنیم، متدهای AddNumbers خواهید دید. با دوبار کلیک کردن روی آن می توانیم اطلاعات مربوط به این متد را در شکل زیر ببینیم.
به نوع داده int32 توجه کنید، همانطور که به یاد دارید در اوایل این مقاله در مورد CTS صحبت کردم که در آن همه انواع داده ها پس از کامپایل برای CTS قابل درک خواهند بود. int در #C و یا Integer در VB به صورت int32 در CTS کامپایل میشوند.
بنابراین همانطور که می بینید متد AddNumbers با استفاده از CIL مانند تصویر بالا نشان داده شده است.
اکنون که متوجه شدید CIL دقیقاً چه کاری انجام می دهد، سوال مطرح میشود که چرا لازم است کد خود را در CIL کامپایل کنید؟
همانطور که قبلا اشاره کردم، ممکن است شما در پروژه جاری خود از زبانهای برنامه نویسی مختلفی در NET. مانند #C و VB استفاده کنید، ولی در نهایت این زبان ها باید به شکل قابل فهمی در CIL کامپایل شوند و با هم تعامل داشته باشند.
این اسمبلی حاوی Metadataهایی مانند کلاس، struct و … است.
پس چگونه این اطلاعات استخراج می شود؟ توسط برنامه نویس یا کامپایلر؟ خوشبختانه تمامی این فرایند ها توسط کامپایلر صورت میگیرد و نیازی به مداخله برنامه نویس نیست.
برای نشان دادن قالب متادیتا، بیایید نگاهی به متادیتا پروژه خود بیاندازیم که توسط متد AddNumbers ایجاد شده است. برای انجام این کار، ideas را در منوی ابزار خود باز کنید و پس از باز شدن کادر گفتگو، کافیست ctl+m را فشار دهید تا متادیتای پروژه خود را مشاهده کنید.
همانطور که در تصویر بالا می بینید، ما یک TypeDef #2 داریم که اطلاعاتی در مورد پروژه ارائه می دهد، برای مثال TypeDefName به کلاس Calc در پروژه Calculator اشاره دارد و همچنین دو متد در کلاس Calc وجود دارد.
حاوی متادیتایی است که خود اسمبلی را توصیف می کند، همانطور که قبلاً اشاره کردم به آن Manifest گفته می شود.
اطلاعات Manifest تمام اطلاعات مجموعه های خارجی مانند شماره نسخه اسمبلی، اطلاعات حق چاپ و غیره را مستند میکند.