اشتراک‌ها
تحقق یک رویا: پشتیبانی توکار از دات نت در همه مرورگرهای مدرن

به لطف استاندارد مدرن و هنوز فراگیر نشده‌ی WebAssembly ، امروزه همه‌ی مرورگر‌های مدرن می‌توانند بجای اجرای جاوا اسکریپت، یک زبان bytecode استانداردِ سطح پایین و شبیه به زبان اسمبلی را اجرا کنند. استفاده از WebAssembly می‌تواند موجب اجرای سریع‌تر کد و کاهش حجم آن شود. اما مهمترین مزیت این هست که امروز می‌توانیم همه‌ی زبان‌های قدرتمند، نظیر سی شارپ را به نحوی کامپایل کنیم که خروجیِ نهایی، منطبق با استاندارد webassembly باشد و به صورت native در مرورگرها، دات نت را اجرا کنیم.

کامپایل سی شارپ به WebAssembly توسط تیم Mono مایکروسافت انجام شده و عمده مشکلات فنی سر راه برداشته شده‌اند. اما برای اینکه عملا بشود از دات نت در مرورگر‌ها استفاده کرد، مایکروسافت در پی پیاده سازی پروژه‌ی جاه طلبانه‌ای به نام Blazor می‌باشد. در واقع Blazor فریم ورک Client-Side مبتنی بر دات نت خواهد بود؛ الهام گرفته از فریم ورک‌های کنونی (مانند Angular و React) و رقیبی جدید برای آن‌ها. فریم ورک Blazor هم مانند آن‌ها حول مفهوم Component شکل گرفته‌است. کامپوننت‌هایی که کلاس‌های سی شارپی هستند و با زبان Razor توسعه داده شده‌اند. 

استفاده از دات نت در مرورگر‌ها می‌تواند موجب این شود که کد بیشتری را بین سرور و کلاینت بتوانیم به اشتراک بگذاریم و نیاز به دوباره کاری در هر دو سمت را نداشته باشیم. علاوه بر این توسعه دهندگان سی شارپ کمی بیشتر به مفهوم Full Stack Developer نزدیک خواهند شد.

همچنین با استفاده از WebAssembly می‌توانیم به تمام کتابخانه‌های موجود جاوااسکریپتی هم دسترسی داشته باشیم و محدودیتی در این زمینه وجود ندارد. همچنین می‌توان DOM را هم از این طریق مدیریت و دستکاری کرد.

در حال حاضر تیم AspNet عهده دار کار بر روی پروژه‌ی Blazor  شده‌است. از نوشته‌های آن‌ها چنین بر می‌آید که تا نهایی شدن این پروژه هنوز باید صبر کنیم.  

تحقق یک رویا: پشتیبانی توکار از دات نت در همه مرورگرهای مدرن
مطالب
آشنایی با CLR: قسمت هفتم
کدهای IL و تایید آن ها

ساختار استکی
IL از ساختار استک استفاده می‌کند. به این معنی که تمامی دستور العمل‌ها داخل آن push شده و نتیجه‌ی اجرای آن‌ها pop می‌شوند. از آنجا که IL به طور مستقیم ارتباطی با ثبات‌ها ندارد، ایجاد زبانهای برنامه نویسی جدید بر اساس CLR بسیار راحت‌تر هست و عمل کامپایل، تبدیل کردن به کدهای IL می‌باشد.

بدون نوع بودن(Typeless)
از دیگر مزیت‌های آن این است که کدهای IL بدون نوع هستند. به این معنی که موقع افزودن دستورالعملی به داخل استک، دو عملگر وارد می‌شوند و هیچ جداسازی در رابطه با سیستم‌های 32 یا 64 بیت صورت نمی‌گیرد و موقع اجرای برنامه است که تصمیم می‌گیرد از چه عملگرهایی باید استفاده شود.

Virtual Address Space
بزرگترین مزیت این سیستم‌ها امنیت و مقاومت آن هاست. موقعی که تبدیل کد IL به سمت کد بومی صورت می‌گیرد، CLR فرآیندی را با نام verification یا تاییدیه، اجرا می‌کند. این فرآیند تمامی کدهای IL را بررسی می‌کند تا از امنیت کدها اطمینان کسب کند. برای مثال بررسی می‌کند که هر متدی صدا زده می‌شود با تعدادی پارامترهای صحیح صدا زده شود و به هر پارامتر آن نوع صحیحش پاس شود و مقدار بازگشتی هر متد به درستی استفاده شود. متادیتا شامل اطلاعات تمامی پیاده سازی‌ها و متدها و نوع هاست که در انجام تاییدیه مورد استفاده قرار می‌گیرد.
در ویندوز هر پروسه، یک آدرس مجازی در حافظه دارد و این جدا سازی حافظه و ایجاد یک حافظه مجازی کاری لازم اجراست. شما نمی‌توانید به کد یک برنامه اعتماد داشته باشید که از حد خود تخطی نخواهد کرد و فرآیند برنامه‌ی دیگر را مختل نخواهد کرد. با خواندن و نوشتن در یک آدرس نامعتبر حافظه، ما این اطمینان را کسب می‌کنیم که هیچ گاه تخطی در حافظه صورت نمی‌گیرد.
قبلا به طور مفصل در این مورد ذخیره سازی در حافظه صحبت کرده ایم.

Hosting
از آنجا که پروسه‌های ویندوزی به مقدار زیادی از منابع سیستم عامل نیاز دارند که باعث کاهش منابع و محدودیت در آن می‌شوند و نهایت کارآیی سیستم را پایین می‌آورد، ولی با کاهش تعدادی برنامه‌های در حال اجرا به یک پروسه‌ی واحد می‌توان کارآیی سیستم را بهبود بخشید و منابع کمتری مورد استفاده قرار می‌گیرند که این یکی دیگر از مزایای کدهای managed نسبت به unmanaged است. CLR در حقیقت این قابلیت را به شما می‌دهد تا چند برنامه‌ی مدیریت شده را در قالب یک پروسه به اجرا درآورید. هر برنامه‌ی مدیریت شده به طور پیش فرض بر روی یک appDomain اجرا می‌گردد و هر فایل EXE روی حافظه‌ی مجازی مختص خودش اجرا می‌شود. هر چند پروسه‌هایی از قبیل IIS و SQL Server که پروسه‌های CLR را پشتیبانی یا هاست می‌کنند می‌توانند تصمیم بگیرند که آیا appDomain‌ها را در یک پروسه‌ی واحد اجرا کنند یا خیر که در مقاله‌های آتی آن را بررسی می‌کنیم.

کد ناامن یا غیر ایمن UnSafe Code
به طور پیش فرض سی شارپ کدهای ایمنی را تولید می‌کند، ولی این اجازه را می‌دهد که اگر برنامه نویس بخواهد  کدهای ناامن بزند، قادر به انجام آن باشد. این کدهای ناامن دسترسی مستقیم به خانه‌های حافظه و دستکاری بایت هاست. این مورد قابلیت قدرتمندی است که به توسعه دهنده اجازه می‌دهد که با کدهای مدیریت نشده ارتباط برقرار کند یا یک الگوریتم با اهمیت زمانی بالا را جهت بهبود کارآیی، اجرا کند.
 هر چند یک کد ناامن سبب ریسک بزرگی می‌شود و می‌تواند وضعیت بسیاری از ساختارهای ذخیره شده در حافظه را به هم بزند و امنیت برنامه را تا حد زیادی کاهش دهد.  به همین دلیل سی شارپ نیاز دارد تا تمامی متدهایی که شامل کد unsafe هستند را با کلمه کلیدی unsafe علامت گذاری کند. همچنین کمپایلر سی شارپ نیاز دارد تا شما این کدها را با سوئیچ unsafe/ کامپایل کنید.

موقعیکه جیت تلاش دارد تا یک کد ناامن را کامپایل کند، اسمبلی را بررسی می‌کند که آیا این متد اجازه و تاییدیه آن را دارد یا خیر. آیا  System.Security.Permissions.SecurityPermission با فلگ SkipVerification مقدار دهی شده است یا خیر. اگر پاسخ مثبت بود JIT آن‌ها را کامپایل کرده و اجازه‌ی اجرای آن‌ها را می‌دهد. CLR به این کد اعتماد می‌کند و امیدوار است که آدرس دهی مستقیم و دستکاری بایت‌های حافظه موجب آسیبی نگردد. ولی اگر پاسخ منفی بود، یک استثناء از نوع System.InvalidProgramException یا System.Security.VerificationException را ایجاد می‌کند تا از اجرای این متد جلوگیری به عمل آید. در واقع کل برنامه خاتمه میابد ولی آسیبی به حافظه نمی‌زند.

پی نوشت: سیستم به  اسمبلی هایی که از روی ماشین یا از طریق شبکه  به اشتراک گذاشته می‌شوند اعتماد کامل میکند که این اعتماد شامل کدهای ناامن هم می‌شود ولی به طور پیش فرض به اسمبلی هایی از طریق اینترنت اجرا می‌شوند اجازه اجرای کدهای ناامن را نمی‌دهد و اگر شامل کدهای ناامن شود یکی از خطاهایی که در بالا به آن اشاره کردیم را صادر می‌کنند. در صورتی که مدیر یا کاربر سیستم اجازه اجرای آن را بدهد تمامی مسئولیت‌های این اجرا بر گردن اوست.

در این زمینه مایکروسافت ابزار سودمندی را با نام PEVerify .exe را معرفی کرده است که به بررسی تمامی متدهای یک اسمبلی پرداخته و در صورت وجود کد ناامن به شما اطلاع میدهد. بهتر است از این موضوع اطلاع داشته باشید که این ابزار نیاز دارد تا به متادیتاهای یک اسمبلی نیاز داشته باشید. باید این ابزار بتواند به تمامی ارجاعات آن دسترسی داشته باشد که در مورد عملیات بایندینگ در آینده بیشتر صحبت می‌کنیم.

IL و حقوق حق تالیف آن
بسیاری از توسعه دهندگان از اینکه IL هیچ شرایطی برای حفظ حق تالیف آن‌ها ایجاد نکرده است، ناراحت هستند. چرا که ابزارهای زیادی هستند که با انجام عملیات مهندسی معکوس می‌توانند به الگوریتم آنان دست پیدا کنند و میدانید که IL خیلی سطح پایین نیست و برگرداندن آن به شکل یک کد، کار راحت‌تری هست و بعضی ابزارها کدهای خوبی هم ارائه می‌کنند. از دست این ابزارها می‌توان به ILDisassembler و  JustDecompile اشاره کرد.
اگر علاقمند هستید این عیب را برطرف کنید، می‌توانید از ابزارهای ثالث که به ابزارهای obfuscator (یک نمونه سورس باز ) معروف هستند استفاده کنید تا با کمی پیچیدگی در متادیتاها، این مشکل را تا حدی برطرف کنند. ولی این ابزارها خیلی کامل نیستند، چرا که نباید به کامپایل کردن کار لطمه بزنند. پس اگر باز خیلی نگران این مورد هستید می‌توانید الگوریتم‌های حساس و اساسی خود را در قالب unmanaged code ارائه کنید که در بالا اشاراتی به آن کرده‌ایم.
برنامه‌های تحت وب به دلیل عدم دسترسی دیگران از امنیت کاملتری برخوردار هستند.
مطالب
Blazor 5x - قسمت اول - معرفی
با استفاده از Blazor می‌توان برنامه‌های وب تعاملی را با کمک زبان #C تهیه کرد که پیشتر برای نوشتن آن‌ها به جاوا اسکریپت نیاز بود. به این ترتیب می‌توان برای تهیه‌ی قسمت‌های front-end و backend پروژه‌ی خود، از زبانی که به آن تسلط دارید استفاده کنید. یکی از مزایای آن امکان به اشتراک گذاری کدهای سمت سرور و کلاینت است؛ با توجه به اینکه هر دو به یک زبان تهیه می‌شوند.


وضعیت توسعه‌ی برنامه‌های وب، پیش از ارائه‌ی Blazor

عموما برای توسعه‌ی برنامه‌های وب، در سمت سرور آن‌ها از زبان‌هایی مانند C#، Java و Python و امثال آن‌ها استفاده می‌شود؛ اما این وضعیت در سمت کلاینت فرق می‌کند. در سمت کلاینت، عموما از فریم‌ورک‌ها و کتابخانه‌های جاوا اسکریپتی مانند Angular ،React ،Vue.js ،jQuery و غیره استفاده می‌شود.


همانطور که مشاهده می‌کنید، فراگیری و اجرای این دو گروه متفاوت از زبان‌ها، مشکل و وقت‌گیر است. بنابراین چقدر خوب می‌شد اگر امکان تهیه‌ی هر دو قسمت برنامه‌های وب، تنها با یک زبان میسر می‌شد. با استفاده از Blazor، این آرزو میسر شده‌است.


با استفاده از Blazor می‌توان کدهای تعاملی UI را بجای استفاده از زبان جاوا اسکریپت، با کمک زبان #C تهیه کرد. به این ترتیب با استفاده از یک زبان می‌توان کدهای سمت سرور و سمت کلاینت را پیاده سازی کرد. البته شاید این سؤال مطرح شود که مرورگرها تنها قادر به درک کدهای HTML و جاوا اسکریپت هستند و نه #C، بنابراین چگونه می‌توان از زبان #C در مرورگرها نیز استفاده کرد؟ پاسخ به آن، به فناوری جدید «وب اسمبلی» بر می‌گردد. Blazor با استفاده از «وب اسمبلی» است که می‌تواند کدهای #C را درون مرورگر اجرا کند.


حالت‌های مختلف هاست و ارائه‌ی برنامه‌های مبتنی بر Blazor

برنامه‌های مبتنی بر Blazor، به دو روش مختلف قابل ارائه هستند:

الف) Blazor Server

Blazor Server، در اساس یک برنامه‌ی استاندارد ASP.NET Core است که در آن تمام قابلیت‌های سمت سرور، مانند کار با EF-Core، میسر است و امکان دسترسی به این امکانات به صورت یکپارچه‌ای در سراسر برنامه وجود دارد. در این حالت، کامپوننت‌های Blazor، بجای اجرای بر روی مرورگر کاربر، در سمت سرور اجرا می‌شوند. این تعاملات و به روز رسانی‌های UI، توسط یک اتصال دائم SignalR مدیریت می‌شوند.


همانطور که مشاهده می‌کنید، در حالت هاست سمت سرور، همه چیز، منجمله کامپوننت‌های Blazor، در همان سمت سرور قرار دارند و این اتصال پشت صحنه‌ی SignalR است که کار تبادل اطلاعات ارسالی و رندر شده را بر عهده می‌گیرد.

ب) Blazor web assembly

در این حالت با استفاده از فناوری جدید «وب اسمبلی»، تمام کدهای یک برنامه‌ی مبتنی بر Blazor به کمک NET Runtime.، داخل مرورگر اجرا می‌شود. به Blazor web assembly باید همانند فریم‌ورک‌های SPA (تک صفحه‌ای وب)، مانند Angular و React نگاه کرد؛ با یک تفاوت مهم: در اینجا بجای استفاده از جاو اسکریپت برای نوشتن برنامه‌ی SPA، از #C استفاده می‌شود. اگر به تصویر فوق دقت کنید، در حالت اجرای برنامه‌های Blazor web assembly، تنها به مرورگر کاربر نیاز است و همه چیز داخل آن قرار می‌گیرد. در اینجا دیگر خبری از یک اتصال دائم SignalR با سرور وجود ندارد.
البته باید دقت داشت که از فناوری وب اسمبلی، در تمام مرورگرهای جدید پشتیبانی می‌شود؛ منهای IE 11. در این حالت مرورگر کل برنامه‌ی Blazor را دریافت می‌کند (همانند دریافت کل کدهای یک برنامه‌ی Angular و یا React) و بدون استفاده از رندر سمت سرور حالت الف، قابلیت تعامل با کاربر را دارد.
بدیهی است با توجه به اینکه Blazor web assembly مستقیما داخل مرورگر اجرا می‌شود، دیگر همانند حالت الف، امکان دسترسی مستقیم به فناوری‌ها و امکانات سمت سرور، مانند کار مستقیم با EF-Core را نخواهد داشت. برای این منظور دقیقا همانند روش کار با سایر فریم ورک‌های SPA، نیاز به تهیه‌ی یک ASP.NET Core Web API جهت تعامل با سرور خواهد بود.


مزایا و معایب حالت‌های مختلف هاست برنامه‌های Blazor

الف) Blazor Server
مزایا:
- حجم دریافتی توسط مرورگر در این حالت بسیار کم است.
- امکان دسترسی به تمام امکانات سمت سرور را دارد؛ مانند تمام کتابخانه‌های سمت سرور و همچنین امکان دیباگ آن نیز همانند سایر برنامه‌های سمت سرور است.
- بر روی مرورگرهای قدیمی نیز قابل اجرا است؛ چون بدون نیاز به فناوری جدید «وب اسمبلی» کار می‌کند.

معایب:
- رندر شدن UI آن نسبت به حالت ب، کندتر است. از این جهت که تمام تعاملات UI آن، توسط اتصال SignalR به سمت سرور ارسال شده و سپس نتیجه‌ی نهایی رندر شده، به سمت کلاینت بازگشت داده می‌شود.
- پشتیبانی از اجرای offline آن وجود ندارد. اگر اتصال SignalR موجود قطع شود، دیگر نمی‌توان از برنامه استفاده کرد.
- با توجه به نیاز به استفاده‌ی از یک اتصال دائم SignalR به ازای هر کاربر، مقیاس پذیری این نوع برنامه‌ها کمتر است. البته اگر تعداد کاربران برنامه‌های شما در یک شبکه‌ی اینترانت داخلی شرکتی محدود است، این مورد مشکل خاصی نخواهد بود. از دیدگاهی دیگر اگر تعداد کاربران برنامه‌ی شما بسیار زیاد است، استفاده از Blazor Server توصیه نمی‌شود. البته باید دقت داشت که سروری با 4GB RAM، می‌تواند 5000 کاربر همزمان SignalR را مدیریت کند.


ب) Blazor web assembly یا به اختصار Blazor WASM
مزایا:
- هیچ نوع وابستگی به سمت سرور ندارد. همینقدر که برنامه توسط مرورگر دریافت شد، قابل اجر است.
- برای هاست آن الزاما نیازی به یک سرور IIS و یا یک وب سرور ASP.NET Core نیست.
- امکان ارائه‌ی آن توسط یک CDN نیز وجود دارد.
- چون در این حالت کل برنامه توسط مرورگر دریافت می‌شود، قابلیت اجرای آفلاین را نیز پیدا می‌کند.
- برای کار، نیازی به اتصال دائم SignalR را ندارد؛ به همین جهت مقیاس پذیری آن بیشتر است.

معایب:
- حتما نیاز به استفاده‌ی از مرورگرهای جدید با پشتیبانی از web assembly را دارد؛ برای مثال نیاز به کروم نگارش 57 به بعد و فایرفاکس نگارش 52 به بعد را دارد و بر روی IE اجرا نمی‌شود.
- چون کل برنامه در این حالت توسط مرورگر دریافت می‌شود، حجم ابتدایی دریافت آن کمی بالا است.
- میدان دید و عملکرد آن همانند سایر برنامه‌های SPA، محدود است به امکاناتی که مرورگر، در اختیار برنامه قرار می‌دهد.



ایجاد پروژه‌های خالی Blazor Server و Blazor web assembly

یا می‌توانید از ویژوال استودیوی کامل و منوی افزودن پروژه‌ی آن برای اینکار استفاده کنید و یا اگر به خروجی دستور dotnet new --list مراجعه کنیم، SDK دات نت 5، به همراه دو قالب مرتبط زیر نیز هست:
C:\Users\Vahid>dotnet new --list
Templates                                         Short Name               Language          Tags
--------------------------------------------      -------------------      ------------      ----------------------
Blazor Server App                                 blazorserver             [C#]              Web/Blazor
Blazor WebAssembly App                            blazorwasm               [C#]              Web/Blazor/WebAssembly
بنابراین فقط کافی است دستور dotnet new blazorserver و یا dotnet new blazorwasm را در یک پوشه‌ی خالی اجرا کنیم تا بر اساس قالب‌های پیش‌فرض ارائه شده، بتوان پروژه‌های خالی Blazor Server و یا Blazor WebAssembly را ایجاد کرد.


در قسمت بعد، این دو پروژه‌ی خالی فوق را ایجاد کرده و ساختار آن‌ها را بررسی می‌کنیم. همچنین نکاتی را هم که در این قسمت در مورد نحوه‌ی هاست این برنامه‌ها عنوان شد، بر روی این پروژه‌ها مشاهده خواهیم کرد.
مطالب
آشنایی با M.A.F - قسمت اول

در طی چند مقاله قصد بررسی نحوه‌ی تولید برنامه‌های توسعه پذیر (extensible) را با استفاده از plug-ins و یا add-ins داریم.

افزونه‌ها عموما در سه گروه قرار می‌گیرند:
الف) افزونه، سرویسی را به هاست ارائه می‌دهد. برای مثال یک میل سرور نیاز به افزونه‌هایی برای ویروس یابی یا فیلتر کردن هرزنامه‌ها دارد؛ یا یک برنامه پردازش متنی نیاز به افزونه‌ای جهت بررسی غلط‌های املایی می‌تواند داشته باشد و یا یک مرورگر وب می‌تواند با کمک افزونه‌ها قابلیت‌های پیش فرض خود را به شدت توسعه و افزایش دهد (نمونه‌ی بارز آن فایرکس است که عمده‌ترین دلیل اقبال عمومی به آن سهولت توسعه پذیری آن می‌باشد).
ب) در گروه دوم، هاست، رفتار مشخصی را ارائه داده و سپس افزونه بر اساس آن، نحوه‌ی عملکرد هاست را مشخص می‌کند. در این حالت هاست است که سرویسی را به افزونه ارائه می‌دهد. نمونه‌ی بازر آن افزونه‌های آفیس هستند که امکان اتوماسیون فرآیندهای مختلف آن‌را میسر می‌سازند. به این صورت امکان توسعه‌ی یک برنامه به شکلی که در طراحی اولیه آن اصلا انتظار آن نمی‌رفته وجود خواهد داشت. همچنین در اینجا نیازی به داشتن سورس کد برنامه‌ی اصلی نیز نمی‌باشد.
ج) گروه سوم افزونه‌ها تنها از هاست جهت نمایش خود استفاده کرده و عملا استفاده‌ی خاصی از هاست ندارد. برای مثال نوار ابزاری که خود را به windows explorer متصل می‌کند و تنها از آن جهت نمایش خود بهره می‌جوید.


در حال حاضر حداقل دو فریم ورک عمده جهت انجام این‌کار و تولید افزونه‌ها برای دات نت فریم ورک مهیا است:
الف) managed addin framework یا MAF
ب) managed extensibility framework یا MEF

فضای نام جدیدی به دات نت فریم ورک سه و نیم به نام System.AddIn اضافه شده است که به آن Managed AddIn Framework یا MAF نیز اطلاق می‌شود. از این فریم ورک در VSTO (تولید افزونه برای مجموعه‌ی آفیس) توسط خود مایکروسافت استفاده شده است.

فریم ورک توسعه‌ی افزونه‌های مدیریت شده در دات نت فریم ورک سه و نیم، مزایای زیر را در اختیار ما خواهد گذاشت:
- امکانات load و unload افزونه‌های تولید شده
- امکان تغییر افزونه‌ها در زمان اجرای برنامه اصلی بدون نیاز به بستن آن
- ارائه‌ی محیطی ایزوله با ترسیم مرزی بین افزونه و برنامه اصلی
- مدیریت طول عمر افزونه
- مدیریت سازگاری با نگارش‌های قبلی و یا بعدی یک افزونه
- امکانات به اشتراک گذاری افزونه‌ها با برنامه‌های دیگر
- تنظیمات امنیتی و مشخص سازی سطح دسترسی افزونه‌ها
و ...

یک راه حل مبتنی بر MAF می‌تواند شامل 7 پروژه باشد (که به روابط تعریف شده در آن pipeline هم گفته می‌شود):

Host : همان برنامه‌ی اصلی است که توسط یک سری افزونه، توسعه یافته است.
Host View : بیانگر انتظارات هاست از افزونه‌ها است. به عبارت دیگر افزونه‌ها باید موارد لیست شده در این پروژه را پیاده سازی کنند.
Host Side Adapter : پل ارتباطی Host View و پروژه‌ی Contract است.
Contract: اینترفیسی است که کار برقراری ارتباط بین Host و افزونه‌ها را برعهده دارد.
Add-In Side Adapter : پل ارتباطی بین Add-In View و Contract است.
Add-In View :‌ حاوی متدها و اشیایی است که جهت برقراری ارتباط با هاست از آن‌ها استفاده می‌شود.
Add-In : اسمبلی است که توسط هاست جهت توسعه‌ی قابلیت‌های خود بارگذاری می‌شود (به آن Add-On ، Extension ، Plug-In و Snap-In هم گفته می‌شود).

هدف از این جدا سازی‌ها ارائه‌ی راه حل loosely-coupledایی است که امکان ایزوله سازی، اعمال شرایط امنیتی ویژه و همچنین کنترل نگارش‌های مختلف را تسهیل می‌بخشد و این امر با استفاده از interface های معرفی شده میسر گردیده است. این pipeline از قسمت‌های ذیل تشکیل می‌شود:



قرار داد یا Contract
برای تولید یک افزونه نیاز است تا بین هاست و افزونه قراردادی بسته شود. با توجه به استفاده از MAF ، روش تعریف این قرار داد برای مثال در یک افزونه‌ی مترجم به صورت زیر باید باشد:

[AddInContract]
public interface ITranslator : IContract
{
string Translate(string input);
}

استفاده از ویژگی AddInContract و پیاده سازی اینترفیس IContract جزو مراحل کاری استفاده از MAF است. MAF هنگام تولید پویای pipeline ذکر شده به دنبال ویژگی AddInContract می‌گردد. این موارد در فضای نام System.AddIn.Pipeline تعریف شده‌اند.

دیدگاه‌ها یا Views
دیدگاه‌ها کدهایی هستند که کار تعامل مستقیم بین افزونه و هاست را بر عهده دارند. هاست یا افزونه هر کدام می‌توانند دیدگاه خود را نسبت به قرار داد بسته شده داشته باشند. این موارد نیز همانند قرار داد در اسمبلی‌های مجزایی نگهداری می‌شوند.

دیدگاه هاست نسبت به قرار داد:
public abstract class TranslatorHostView
{
public abstract string Translate(string input);
}
دیدگاه افزونه نسبت به قرار داد:
[AddInBase]
public abstract class TranslatorHostView
{
public abstract string Translate(string input);
}

هر دو کلاس فوق بر اساس قرار موجود بنا می‌شوند اما وابسته به آن نیستند. به همین جهت به صورت کلاس‌هایی abstract تعریف شده‌اند. در سمت افزونه، کلاس تعریف شده دیدگاه آن با کلاس دیدگاه سمت هاست تقریبا یکسان می‌باشد؛ اما با ویژگی AddInBase تعریف شده در فضای نام System.AddIn.Pipeline مزین گردیده است.


وفق دهنده‌ها یا Adapters
آخرین قسمت pipeline ، وفق دهنده‌ها هستند که کار آن‌ها اتصال قرار داد به دیدگاه‌ها است و توسط آن مدیریت طول عمر افزونه و همچنین تبدیل اطلاعات بین قسمت‌های مختلف انجام می‌شود. شاید در نگاه اول وجود آن‌ها زائد به نظر برسد اما این جدا سازی کدها سبب تولید افزونه‌هایی خواهد شد که به نگارش هاست و برنامه اصلی وابسته نبوده و بر عکس (version tolerance). به دو کلاس زیر دقت نمائید:

کلاس زیر با ویژگی [HostAdapter] تعریف شده در فضای نام System.AddIn.Pipeline، مزین شده است و کار آن اتصال HostView به Contract می‌باشد. برای این منظور TranslatorHostView ایی را که پیشتر معرفی کردیم باید پیاده سازی نماید. علاوه بر این با ایجاد وهله‌ای از کلاس ContractHandle ، کار مدیریت طول عمر افزونه را نیز می‌توان انجام داد.

[HostAdapter]
public class TranslatorHostViewToContract : TranslatorHostView
{
ITranslator _contract;
ContractHandle _lifetime;

public TranslatorHostViewToContract(ITranslator contract)
{
_contract = contract;
_lifetime = new ContractHandle(contract);
}

public override string Translate (string inp)
{
return _contract.Translate(inp);
}
}
کلاس سمت افزونه نیز بسیار شبیه قسمت قبل است و کار آن اتصال AddInView به Contract می‌باشد که با پیاده سازی ContractBase و Itranslator صورت خواهد گرفت. همچنین این کلاس به ویژگی AddInAdapter مزین گردیده است.

[AddInAdapter]
public class TranslatorAddInViewToContract : ContractBase, ITranslator
{
TranslatorAddInView _view;

public TranslatorAddInViewToContract(TranslatorView view)
{
_view = view;
}

public string Translate(string inp)
{
return _view.Translate(inp);
}
}

قسمت عمده‌ای از این کدها تکراری است. جهت سهولت تولید این کلاس‌ها و پروژه‌های مرتبط، تیم مربوطه برنامه‌ای را به نام pipeline builder ارائه داده است که از آدرس زیر قابل دریافت است:


این برنامه با دریافت اسمبلی مربوط بهcontract ، کار ساخت خودکار کلاس‌های adapters و views را انجام خواهد داد.

ایجاد افزونه
پس از ساخت قسمت‌های مختلف pipeline ، اکنون می‌توان افزونه را ایجاد نمود. هر افزونه باید add-in view را پیاده سازی کرده و با ویژگی AddIn مزین شود. برای مثال:

[AddIn("GoogleTranslator", Description="Universal translator",
Version="1.0.0.0", Publisher="YourName")]
public class GoogleAddIn : TranslatorAddInView
{
public string Translate(string input)
{
...
}
}

ادامه دارد ....

مطالب
هزینه استفاده از دات نت فریم ورک چقدر است؟

سؤالی از طریق ایمیل از من پرسیده شده که ترجیح می‌دهم آن‌را به صورت باز در اینجا پاسخ دهم. اگر فرض کنیم همین فردا مجبور شویم برای عمده‌ی کارهای خود لایسنس تهیه کنیم، آیا می‌توان از ابزارهای موجود دات نت در یک شرکت تازه تاسیس (startup) استفاده کرد؟ آیا هزینه‌ی کار با ویندوز واقعا بالا است؟ آیا ...
همچنین عموم تازه واردان به این جمع هم از لیست امکانات رایگان مهیا که فقط پس از خرید یک لایسنس اولیه ویندوز در اختیار آن‌ها خواهند بود، بی‌اطلاع هستند. بنابراین بد نیست این‌ها را با هم لیست کنیم.

سؤال: هزینه استفاده از دات نت فریم ورک چقدر است؟
پاسخ: رایگان است! از زمان ارائه ویندوز سرور 2003 به بعد، دات نت فریم ورک به عنوان یکی از کامپوننت‌های اصلی ویندوز عرضه می‌شود و هر شخصی که مجوز اصلی استفاده از ویندوز را خریده باشد، به صورت خودکار مجوز استفاده از دات نت فریم ورک را هم خواهد داشت و نیازی نیست بابت آن هزینه‌ی خاصی را متقبل شود. برای مثال ویندوز سرور 2003 ، دات نت 1.1 سرخود است و ویندوز 7 و ویندوز سرور 2008 ، دات نت سه و نیم سرخود هستند.

سؤال: آیا برای توسعه‌ی دات نت حتما نیاز است تا ویژوال استودیوی چند هزار دلاری را خرید؟!
پاسخ: خیر! ویژوال استودیو، نسخه‌های مختلفی دارد و حتما نیازی نیست تا از نسخه‌ی ultimate آن استفاده کنید. برای مثال نسخه‌ی Express آن که توسط خود مایکروسافت ارائه شده، رایگان است (+). مهم‌ترین تفاوت آن با نسخه‌ی ultimate در این است که افزونه پذیر نیست و این مورد شاید برای خیلی‌ها اصلا اهمیتی نداشته باشد چون عموما افزونه‌های بد نوشته شده، باعث ناپایداری IDE می‌شوند یا مثلا نسخه‌ی ultimate به همراه MSTests جهت انجام ساده‌تر unit testing‌ ارائه شده که در نسخه‌ی Express وجود ندارد، این هم مهم نیست چون فریم ورک‌های سورس باز آزمون واحد دیگری مانند Nunit ، MBUnit و غیره هم وجود دارند که اصلا نیازی به هیچ IDE‌ خاصی جهت کار ندارند و مسایلی از این دست. یا برای سورس کنترل می‌شود از SVN ، Git ، مرکوریال و غیره هم همیشه استفاده کرد. این‌ها هم مستقل هستند از نوع IDE مورد استفاده.

همچنین یک گروه مستقل، IDE دیگری را به نام SharpDevelop تهیه کر‌ده‌اند که بسیار با کیفیت بوده و از همه مهم‌تر سورس باز است و رایگان. خیلی‌ها از کنترل‌های این IDE در پروژه‌های خودشون استفاده می‌کنند (مثل syntax highlighting همراه آن و غیره)

در کنار تمام این‌ها، هیچ وقت دقت کرده‌اید که در پوشه دات نت نصب شده در ویندوز چه چیزهایی یافت می‌شوند؟! مثلا به آدرس C:\Windows\Microsoft.NET\Framework\v4.0.30319 مراجعه کنید. فایل csc.exe همان کامپایلر خط فرمان سی شارپ است. کاری هم که IDE ها انجام می دهند این است که لیست فایل‌های شما رو به صورت آرگومان به این برنامه ارسال می‌کنند. این اتوماسیون به صورت دستی هم میسر است. IDE شما می‌شود مثلا برنامه رایگان notepad++ ایی که syntax highlighting تمام زبان‌های دات نتی را پشتیبانی می‌کند. ساده‌ترین سیستم build شما یک فایل bat خواهد بود که csc.exe را مدیریت می‌کند.

علاوه بر تمام این‌ها، MonoDevelop را هم اضافه کنید. این IDE ، نسخه‌ی ویندوزی هم دارد.

سؤال: من شنیدم دات نت فقط با SQL Server کار می‌کنه. این هم که گرونه؟!
پاسخ: خیر! نسخه‌ی رایگان SQL server به نام SQL Server express هم موجود است و در نسخه‌ی 2008 R2 آن محدودیت حجم بانک اطلاعاتی آن به 10 گیگ رسیده که برای اکثر کارها تا چند سال کافی است (+).
ضمنا قبلا در مورد لیست بانک‌های اطلاعاتی قابل استفاده توسط دات نت فریم ورک مطلب نوشتم و در سایت موجود است. بنابراین دات نت اصلا به SQL Server محدود نیست (+).

سؤال: دات نت سورس بسته است! نه این اصلا خوب نیست؛ آینده نداره!
پاسخ: خیر. سورس کامل دات نت فریم ورک تحت مجوز‌های MS-PL و MS-RSL چندسالی هست که منتشر شده و این مجوز (MS-PL) جزو مجوزهای معتبر و پذیرفته شده سورس باز است (+).
لینک دریافت

خبر مرتبط

ضمنا کارهای سورس باز مایکروسافت به این یک قلم ختم نمی‌شود. برای مثال به سایت CodePlex مراجعه کنید تا سورس کامل ASP.NET MVC نگارش 3 را دریافت کنید(+)، همینطور مجموعه کنترل‌های WPF و Silverlight و غیره‌ای که تهیه‌ کرده‌اند (+) و بسیاری موارد دیگر.

سؤال: دات نت که فقط روی ویندوز اجرا میشه. نه؛ این خوب نیست!
پاسخ: خیر! پروژه‌ای سابقا تحت عنوان Mono وجود دارد/داشت (+) که توسط شرکت ناول اداره می‌شد و کار آن انتقال دات نت به لینوکس و سایر سکوهای کاری بود. پس از فروخته شدن ناول، این پروژه به ظاهر متوقف شد، اما تیم اصلی آن تحت نام دیگری به نام زاماریان (+) دوباره شروع به کار کرده و جالب اینجا است که تا دات نت 4 را هم تحت لینوکس پشتیبانی می‌کند(+). جهت اطلاع ASP.NET رو به صورت کامل می‌تونید تحت لینوکس اجرا کنید (+). همچنین سایر موارد پشتیبانی شده رو.


سؤال: وضعیت بازار کار دات نت در ایران چطور است؟
پاسخ: آقای محبی برنامه‌ای رو درست کرده‌اند به نام کارویس که من مدتی است مشترک فید آن هستم تا حدودا از نیازهای عمومی بازار کار برنامه نویسی ایران اطلاع کسب کنم (+). نکته‌ی جالبی که در فید این برنامه مشخص است، درخواست بالای نیاز به برنامه نویس دات نت در کشور است. بالای 80 درصد آگهی‌ها نیاز به برنامه نویس دات نت دارند.


در کنار تمام این مباحث، بحث «هزینه یادگیری و آموزش» را هم اضافه کنید. شاید یکی بیاد بگه CPP فلان، اون یکی بهمان! ولی این سؤالات هم برای من نوعی که تیم گوگل کروم نوشته شده با CPP رو مدیریت نمی‌کنم (و به قول اونطرف آبی‌ها یک Average Joe هستم!) مهم هستند:
- چندتا کتاب فارسی آموزشی خوب در این زمینه در کشور موجود است. من یادم میاد اولین کتاب VC منتشر شده در کشور پس از 450 صفحه به شما یاد می‌داد چطور با MFC دکمه به صفحه اضافه کنید، چطور منو درست کنید و همین! این شد برنامه نویسی CPP!
- چند عدد انجمن رفع اشکال فعال را که تاریخ آخرین به روز رسانی و پرسش و پاسخ آن‌ها مثلا دیروز بوده را در مورد زبان xyz می‌توان یافت؟
- اگر به مشکل برخوردم، کسی هست به داد من برسه؟ چه زمانی؟! مثلا هفته بعد یا تا آخر امروز؟
- چندتا وبلاگ فعال در این زمینه موجود است؟ آیا هستند کسانی که در این زمینه‌ها فعالانه مطلب منتشر کنند؟ اطلاع رسانی کنند؟
- اگر کارمند برنامه نویس شرکتی امروز قهر کرد، مدیر بخش توسعه تا چه زمانی می‌تونه یک نفر رو جایگزین اون کنه؟ مثلا تا آخر ماه یا تا آخر سال؟! اون هم با چه کیفیتی؟ با چه دستمزدی؟
و اینجا است که وضعیت دات نت در ایران بسیار مطلوب‌تر از موارد مشابه به نظر می‌رسد. از نظر تعداد کتاب فارسی مهیا، تعداد انجمن، تعداد وبلاگ فعال و غیره.

مطالب
هزینه استفاده از دات نت فریم ورک چقدر است؟

سؤالی از طریق ایمیل از من پرسیده شده که ترجیح می‌دهم آن‌را به صورت باز در اینجا پاسخ دهم. اگر فرض کنیم همین فردا مجبور شویم برای عمده‌ی کارهای خود لایسنس تهیه کنیم، آیا می‌توان از ابزارهای موجود دات نت در یک شرکت تازه تاسیس (startup) استفاده کرد؟ آیا هزینه‌ی کار با ویندوز واقعا بالا است؟ آیا ...
همچنین عموم تازه واردان به این جمع هم از لیست امکانات رایگان مهیا که فقط پس از خرید یک لایسنس اولیه ویندوز در اختیار آن‌ها خواهند بود، بی‌اطلاع هستند. بنابراین بد نیست این‌ها را با هم لیست کنیم.

سؤال: هزینه استفاده از دات نت فریم ورک چقدر است؟
پاسخ: رایگان است! از زمان ارائه ویندوز سرور 2003 به بعد، دات نت فریم ورک به عنوان یکی از کامپوننت‌های اصلی ویندوز عرضه می‌شود و هر شخصی که مجوز اصلی استفاده از ویندوز را خریده باشد، به صورت خودکار مجوز استفاده از دات نت فریم ورک را هم خواهد داشت و نیازی نیست بابت آن هزینه‌ی خاصی را متقبل شود. برای مثال ویندوز سرور 2003 ، دات نت 1.1 سرخود است و ویندوز 7 و ویندوز سرور 2008 ، دات نت سه و نیم سرخود هستند.

سؤال: آیا برای توسعه‌ی دات نت حتما نیاز است تا ویژوال استودیوی چند هزار دلاری را خرید؟!
پاسخ: خیر! ویژوال استودیو، نسخه‌های مختلفی دارد و حتما نیازی نیست تا از نسخه‌ی ultimate آن استفاده کنید. برای مثال نسخه‌ی Express آن که توسط خود مایکروسافت ارائه شده، رایگان است (+). مهم‌ترین تفاوت آن با نسخه‌ی ultimate در این است که افزونه پذیر نیست و این مورد شاید برای خیلی‌ها اصلا اهمیتی نداشته باشد چون عموما افزونه‌های بد نوشته شده، باعث ناپایداری IDE می‌شوند یا مثلا نسخه‌ی ultimate به همراه MSTests جهت انجام ساده‌تر unit testing‌ ارائه شده که در نسخه‌ی Express وجود ندارد، این هم مهم نیست چون فریم ورک‌های سورس باز آزمون واحد دیگری مانند Nunit ، MBUnit و غیره هم وجود دارند که اصلا نیازی به هیچ IDE‌ خاصی جهت کار ندارند و مسایلی از این دست. یا برای سورس کنترل می‌شود از SVN ، Git ، مرکوریال و غیره هم همیشه استفاده کرد. این‌ها هم مستقل هستند از نوع IDE مورد استفاده.
همچنین یک گروه مستقل، IDE دیگری را به نام SharpDevelop تهیه کر‌ده‌اند که بسیار با کیفیت بوده و از همه مهم‌تر سورس باز است و رایگان. خیلی‌ها از کنترل‌های این IDE در پروژه‌های خودشون استفاده می‌کنند (مثل syntax highlighting همراه آن و غیره)

در کنار تمام این‌ها، هیچ وقت دقت کرده‌اید که در پوشه دات نت نصب شده در ویندوز چه چیزهایی یافت می‌شوند؟! مثلا به آدرس C:\Windows\Microsoft.NET\Framework\v4.0.30319 مراجعه کنید. فایل csc.exe همان کامپایلر خط فرمان سی شارپ است. کاری هم که IDE ها انجام می دهند این است که لیست فایل‌های شما رو به صورت آرگومان به این برنامه ارسال می‌کنند. این اتوماسیون به صورت دستی هم میسر است. IDE شما می‌شود مثلا برنامه رایگان notepad++ ایی که syntax highlighting تمام زبان‌های دات نتی را پشتیبانی می‌کند. ساده‌ترین سیستم build شما یک فایل bat خواهد بود که csc.exe را مدیریت می‌کند.

سؤال: من شنیدم دات نت فقط با SQL Server کار می‌کنه. این هم که گرونه؟!
پاسخ: خیر! نسخه‌ی رایگان SQL server به نام SQL Server express هم موجود است و در نسخه‌ی 2008 R2 آن محدودیت حجم بانک اطلاعاتی آن به 10 گیگ رسیده که برای اکثر کارها تا چند سال کافی است (+).
ضمنا قبلا در مورد لیست بانک‌های اطلاعاتی قابل استفاده توسط دات نت فریم ورک مطلب نوشتم و در سایت موجود است. بنابراین دات نت اصلا به SQL Server محدود نیست (+).

سؤال: دات نت سورس بسته است! نه این اصلا خوب نیست؛ آینده نداره!
پاسخ: خیر. سورس کامل دات نت فریم ورک تحت مجوز MS-PL چندسالی هست که منتشر شده و این مجوز جزو مجوزهای معتبر و پذیرفته شده سورس باز است (+).
لینک دریافت

خبر مرتبط

ضمنا کارهای سورس باز مایکروسافت به این یک قلم ختم نمی‌شود. برای مثال به سایت CodePlex مراجعه کنید تا سورس کامل ASP.NET MVC نگارش 3 را دریافت کنید(+)، همینطور مجموعه کنترل‌های WPF و Silverlight و غیره‌ای که تهیه‌ کرده‌اند (+) و بسیاری موارد دیگر.

سؤال: دات نت که فقط روی ویندوز اجرا میشه. نه؛ این خوب نیست!
پاسخ: خیر! پروژه‌ای سابقا تحت عنوان Mono وجود دارد/داشت (+) که توسط شرکت ناول اداره می‌شد و کار آن انتقال دات نت به لینوکس و سایر سکوهای کاری بود. پس از فروخته شدن ناول، این پروژه به ظاهر متوقف شد، اما تیم اصلی آن تحت نام دیگری به نام زاماریان (+) دوباره شروع به کار کرده و جالب اینجا است که تا دات نت 4 را هم تحت لینوکس پشتیبانی می‌کند(+). جهت اطلاع ASP.NET رو به صورت کامل می‌تونید تحت لینوکس اجرا کنید (+). همچنین سایر موارد پشتیبانی شده رو.


سؤال: وضعیت بازار کار دات نت در ایران چطور است؟
پاسخ: آقای محبی برنامه‌ای رو درست کرده‌اند به نام کارویس که من مدتی است مشترک فید آن هستم تا حدودا از نیازهای عمومی بازار کار برنامه نویسی ایران اطلاع کسب کنم (+). نکته‌ی جالبی که در فید این برنامه مشخص است، درخواست بالای نیاز به برنامه نویس دات نت در کشور است. بالای 80 درصد آگهی‌ها نیاز به برنامه نویس دات نت دارند.


در کنار تمام این مباحث، بحث «هزینه یادگیری و آموزش» را هم اضافه کنید. شاید یکی بیاد بگه CPP فلان، اون یکی بهمان! ولی این سؤالات هم برای من نوعی که تیم گوگل کروم نوشته شده با CPP رو مدیریت نمی‌کنم (و به قول اونطرف آبی‌ها یک Average Joe هستم!) مهم هستند:
- چندتا کتاب فارسی آموزشی خوب در این زمینه در کشور موجود است. من یادم میاد اولین کتاب VC منتشر شده در کشور پس از 450 صفحه به شما یاد می‌داد چطور با MFC دکمه به صفحه اضافه کنید، چطور منو درست کنید و همین! این شد برنامه نویسی CPP!
- چند عدد انجمن رفع اشکال فعال را که تاریخ آخرین به روز رسانی و پرسش و پاسخ آن‌ها مثلا دیروز بوده را در مورد زبان xyz می‌توان یافت؟
- اگر به مشکل برخوردم، کسی هست به داد من برسه؟ چه زمانی؟! مثلا هفته بعد یا تا آخر امروز؟
- چندتا وبلاگ فعال در این زمینه موجود است؟ آیا هستند کسانی که در این زمینه‌ها فعالانه مطلب منتشر کنند؟ اطلاع رسانی کنند؟
- اگر کارمند برنامه نویس شرکتی امروز قهر کرد، مدیر بخش توسعه تا چه زمانی می‌تونه یک نفر رو جایگزین اون کنه؟ مثلا تا آخر ماه یا تا آخر سال؟! اون هم با چه کیفیتی؟ با چه دستمزدی؟
و اینجا است که وضعیت دات نت در ایران بسیار مطلوب‌تر از موارد مشابه به نظر می‌رسد. از نظر تعداد کتاب فارسی مهیا، تعداد انجمن، تعداد وبلاگ فعال و غیره.

مطالب
خواندنی‌های 19 فروردین

- ویدیوی رایگان آموزشی در مورد جنبه‌های مختلف LINQ to Entities (دریافت، ماخذ)

- Mono و پشتیبانی از SIMD یا Single Instruction Multiple Data
برنامه نویسی موازی تنها به برنامه نویسی چند ریسمانی و چند هسته‌ای خلاصه نمی‌شود. بلکه استفاده از توانایی‌های پیشرفته در پروسسورهای مدرن امروزی Intel و AMD نیز توانایی قابل توجهی را در این عرصه ارائه می‌دهند. بسیاری از برنامه‌های نوشته شده به زبان‌های C و CPP از SIMD جهت بالا بردن سرعت پردازشی استفاده می‌کنند ( برای مثال بالا بردن سرعت کار با ماتریس‌ها و بردارها یا بهینه سازی حلقه‌ها) و کامپایلرهای آن‌ها نیز در این زمینه امکانات ویژه‌ای را ارائه ‌می‌نمایند. اما زبان‌های بر پایه دات نت راه ساده‌ای را برای استفاده از این توانایی ندارند.
با ارائه مونو 2.2 (شماره نگارش‌های مونو (دات نت لینوکسی) با شماره نگارش‌های دات نت فریم ورک مایکروسافت همخوانی ندارد و مستقل هستند)، این سناریو تغییر کرده است و فضای نام Mono.Simd ارائه شده است. به این صورت می‌توان از توانایی‌های SIMD (تنها SSE3 و قسمتی از SSE4 پشتیبانی می‌شود) در برنامه‌های دات نت استفاده نمود (که بیشتر بر روی عملیات سریع بر روی ماتریس‌ها و بردارها متمرکز شده است).
جهت اطلاعات بیشتر می‌توان به دمویی در اینباره رجوع کرد. دریافت
ماخذ

- کارت‌های مرجع دات نت
سایت Dzone اخیرا در تکمیل برگه‌های مرجع پیشین خود، برگه‌های مرجع ASP.Net را نیز ارائه کرده است.
Core ASP.NET
برای دریافت نیاز به ثبت نام است و سپس درخواست لینک دانلود که به آدرس ایمیل شما ارسال خواهد شد.

مطالب
اندازه گیری کارآیی کدها توسط NBench
این روزها جهت اندازه‌گیری کارآیی قطعات کدهای دات نتی، استفاده از فریم ورک‌های مخصوصی که بسیاری از نکات ریز مرتبط با اینگونه اندازه‌گیری‌ها را مانند warmup یا گرم کردن JIT (جهت عدم اندازه گیری زمان کامپایل پویای کدها، بجای زمان واقعی اجرای آن‌ها)، اندازه‌گیری فشار بر روی Garbage collector و غیره را انجام می‌دهند، بجای استفاده‌ی از Stop Watch، متداول است. یکی از معروفترین‌های این گروه، که تقریبا حالت استانداردی را در جهت اندازه گیری کارآیی کدهای دات نتی پیدا کرده‌است، فریم ورک سورس باز NBench است.


شروع به کار با NBench

برای شروع به کار با NBench، ابتدا نیاز است دو بسته‌ی نیوگت ذیل را نصب کرد:
PM> Install-Package NBench
PM> Install-Package NBench.Runner
عملکرد این فریم ورک، شبیه به عملکرد فریم ورک‌های آزمون‌های واحد است. برای مثال فرض کنید که می‌خواهید فشار حافظه و فشار بر روی GC قطعه کدی را اندازه گیری کنید:
[PerfBenchmark(RunMode = RunMode.Iterations, TestMode = TestMode.Measurement)]
[MemoryMeasurement(MemoryMetric.TotalBytesAllocated)]
public void AddMemoryMeasurement()
{
    const int numberOfAdds = 1000000;
    var dictionary = new Dictionary<int, int>();
    for (var i = 0; i < numberOfAdds; i++)
    {
        dictionary.Add(i, i);
    }
}
 
[PerfBenchmark(RunMode = RunMode.Iterations, TestMode = TestMode.Measurement)]
[GcMeasurement(GcMetric.TotalCollections, GcGeneration.AllGc)]
public void MeasureGarbageCollections()
{
    var dataCache = new List<int[]>();
    for (var i = 0; i < 500; i++)
    {
        for (var j = 0; j < 10000; j++)
        {
            var data = new int[100];
            dataCache.Add(data.ToArray());
        }
 
        dataCache.Clear();
    }
}
همانند نوشتن متدهای آزمون‌های واحد، ابتدا یک یا چند متد public void را در اینجا اضافه می‌کنیم.
سپس هر متد تست به ویژگی PerfBenchmark مزین می‌شود. در اینجا RunMode.Iterations به این معنا است که خودمان قصد داریم در طی یک حلقه، تعداد بار انجام را مشخص کنیم.
ویژگی MemoryMeasurement برای اندازه گیری حافظه‌ی مصرفی یک قطعه کد و GcMeasurement برای اندازه گیری فشار بر روی Garbage collector بکار می‌رود.


اجرای آزمون‌های NBench

پس از تهیه‌ی دو متد فوق، به پوشه‌ی packages\NBench.Runner.0.3.4\lib\net45 مراجعه کنید. یک فایل exe در آن موجود است که کار یافتن و اجرای آزمون‌های NBench را انجام می‌دهد. به عنوان پارامتر آن تنها کافی است مسیر اسمبلی برنامه (فایل exe و یا dll) را به آن ارسال کنیم:
 D:\Prog\NBenchSample\packages\NBench.Runner.0.3.4\lib\net45\NBench.Runner.exe "D:\Prog\NBenchSample\NBenchSample\bin\Release\NBenchSample.exe"
پس از آن، کار اجرای آزمون‌های NBench شروع شده و پس از مدتی ابتدا BEGIN WARMUP و END WARMUP‌ها را می‌توان مشاهده کرد و در آخر یک چنین خروجی ارائه می‌شود:
 --------------- RESULTS: NBenchSample.Program+AddMemoryMeasurement ---------------
TotalBytesAllocated: Max: 47,842,944.00 bytes, Average: 42,002,757.60 bytes, Min: 41,353,848.00 bytes, StdDev: 2,052,032.33 bytes
TotalBytesAllocated: Max / s: 359,074,078.19 bytes, Average / s: 311,474,786.96 bytes, Min / s: 300,926,928.79 bytes, StdDev / s: 16,869,581.62 bytes

--------------- RESULTS: NBenchSample.Program+MeasureGarbageCollections ---------------
TotalCollections [Gen0]: Max: 708.00 collections, Average: 702.80 collections, Min: 697.00 collections, StdDev: 3.65 collections
TotalCollections [Gen0]: Max / s: 111.55 collections, Average / s: 109.87 collections, Min / s: 107.88 collections, StdDev / s: 1.28 collections

TotalCollections [Gen1]: Max: 338.00 collections, Average: 334.60 collections, Min: 330.00 collections, StdDev: 2.41 collections
TotalCollections [Gen1]: Max / s: 53.61 collections, Average / s: 52.31 collections, Min / s: 51.10 collections, StdDev / s: 0.70 collections

TotalCollections [Gen2]: Max: 32.00 collections, Average: 24.80 collections, Min: 18.00 collections, StdDev: 4.73 collections
TotalCollections [Gen2]: Max / s: 4.91 collections, Average / s: 3.87 collections, Min / s: 2.86 collections, StdDev / s: 0.72 collections


نکته‌ای در مورد اندازه گیری فشار حافظه

حافظه توسط سیستم عامل، به صورت صفحات تخصیص داده می‌شود. برای مثال اگر شما به 12 بایت نیاز داشته باشید، سیستم عامل ممکن است 8 کیلوبایت را جهت کاهش تعداد بار تخصیص‌های حافظه و بالا بردن سرعت کار، در اختیار برنامه قرار دهد. بنابراین جهت رسیدن به بهترین نتیجه، در اینجا بهتر است تعداد زیادی شیء را مورد آزمایش قرار داد. برای مثال در آزمایش فوق بجای افزودن یک آیتم به دیکشنری، افزودن میلیون‌ها شیء، نویز استراتژی تخصیص حافظه‌ی توسط سیستم عامل را به حداقل می‌رساند.

شبیه به همین استراتژی، در پیاده سازی Dictionary نیز بکارگرفته شده‌است:
[PerfBenchmark(RunMode = RunMode.Iterations, TestMode = TestMode.Measurement)]
[MemoryMeasurement(MemoryMetric.TotalBytesAllocated)]
public void AddMemoryMeasurement_With_initial_Size()
{
    const int numberOfAdds = 1000000;
    var dictionary = new Dictionary<int, int>(numberOfAdds);
    for (var i = 0; i < numberOfAdds; i++)
    {
        dictionary.Add(i, i);
    }
}
اگر اینبار این آزمون را انجام دهیم، به نتیجه‌ی ذیل خواهیم رسید:
 --------------- RESULTS: NBenchSample.Program+AddMemoryMeasurement_With_initial_Size ---------------
TotalBytesAllocated: Max: 23,245,912.00 bytes, Average: 23,245,912.00 bytes, Min: 23,245,912.00 bytes, StdDev: 0.00 bytes
TotalBytesAllocated: Max / s: 394,032,435.34 bytes, Average / s: 389,108,363.43 bytes, Min / s: 378,502,981.34 bytes, StdDev / s: 5,575,519.09 bytes
در اینجا زمانیکه شیء دیکشنری ایجاد شده‌است، اندازه‌ی اولیه‌ی آن نیز مشخص گردیده‌است. همین مساله سبب شده‌است تا مصرف حافظه‌ی آن از نزدیک به 41 مگابایت (متد AddMemoryMeasurement ابتدای بحث) به نزدیک 24 مگابایت (متد AddMemoryMeasurement_With_initial_Size فوق) کاهش یابد.
علت اینجا است که دیکشنری در پشت صحنه، از یک متد ReSize استفاده می‌کند که شبیه به سیستم عامل، بیشتر از مقدار مورد نیاز جهت ذخیره‌ی اشیاء، برای کاهش تعداد بار تخصیص‌های حافظه، حافظه به خود اختصاص می‌دهد. به همین جهت زمانیکه اندازه‌ی اولیه را مشخص کرد‌ه‌ایم، کار تخصیص حافظه‌ی بیش از اندازه‌ی این شیء، به شدت کاهش یافته‌است.


بررسی متد MeasureGarbageCollections

در متد MeasureGarbageCollections، مقدار زیادی شیء بر روی heap ایجاد شده و GC را وادار به عکس العمل شدید می‌کند.
حلقه‌ی داخلی ایجاد شده نیز تعداد زیادی شیء را در جهت پاکسازی GC تخصیص می‌دهد. این پاکسازی در مرحله‌ا‌ی به نام generation 0 صورت می‌گیرد.
اشیاء اضافه شده‌ی به لیست، طول عمر بیشتری دارند (تا پایان حلقه). بنابراین از garbage collection at generation 0 جان سالم به در خواهند برد و در garbage collection at generation 1  به عمر آن‌ها پایان داده خواهد شد. هرچند ممکن است تعدادی از آن‌ها پاکسازی نشده و تا پایان full garbage collection (generation 2) باقی بمانند.
در آزمایش انجام شده، با ذکر GcGeneration.AllGc، هر سه مورد Gen0 تا Gen2 اندازه گیری خواهند شد. عموما اندازه گیری Gen0 و Gen1 مهم نیستند و این‌ها خیلی زود به پایان خواهند رسید. اگر تعداد بار رخ‌دادن Gen2 زیاد بود (یا اصلا وجود داشت)، می‌تواند سبب بروز مشکلات کارآیی شدیدی گردد.
بنابراین می‌توان بجای تنظیم GcGeneration.AllGc، صرفا از GcGeneration.Gen2 استفاده کرد.


اندازه‌گیری Throughput یا تعداد بار اجرای یک متد در ثانیه

روش دیگر کار با فریم ورک NBench، ایجاد یک کلاس مخصوص و سپس افزودن متدهای Setup مزین به PerfSetup، متد Cleanup مزین به PerfCleanup و سپس تعدادی متد اندازه گیری کارآیی توسط ویژگی PerfBenchmark است. در اینجا برای اندازه‌گیری سرعت اجرای متدها، از ویژگی CounterThroughputAssertion استفاده خواهد شد که پارامتر اول آن نام یک شمارشگر است. این شمارشگر در متد Setup ایجاد می‌شود (با یک نام دلخواه).
public class DictionaryThroughputTests
{
    private readonly Dictionary<int, int> _dictionary = new Dictionary<int, int>();
 
    private const string AddCounterName = "AddCounter";
    private Counter _addCounter;
    private int _key;
 
    private const int AverageOperationsPerSecond = 20000000;
 
    [PerfSetup]
    public void Setup(BenchmarkContext context)
    {
        _addCounter = context.GetCounter(AddCounterName);
        _key = 0;
    }
 
    [PerfBenchmark(RunMode = RunMode.Throughput, TestMode = TestMode.Test)]
    [CounterThroughputAssertion(AddCounterName, MustBe.GreaterThan, AverageOperationsPerSecond)]
    public void AddThroughput_ThroughputMode(BenchmarkContext context)
    {
        _dictionary.Add(_key++, _key);
        _addCounter.Increment();
    }
 
    [PerfBenchmark(RunMode = RunMode.Iterations, TestMode = TestMode.Test)]
    [CounterThroughputAssertion(AddCounterName, MustBe.GreaterThan, AverageOperationsPerSecond)]
    public void AddThroughput_IterationsMode(BenchmarkContext context)
    {
        for (var i = 0; i < AverageOperationsPerSecond; i++)
        {
            _dictionary.Add(i, i);
            _addCounter.Increment();
        }
    }
 
    [PerfCleanup]
    public void Cleanup(BenchmarkContext context)
    {
        _dictionary.Clear();
    }
}
در این آزمایش‌ها، RunMode.Throughput به معنای اجرای متد آزمایش به تعداد AverageOperationsPerSecond توسط فریم ورک NBench است. در حالت قید RunMode.Iterations، تعداد بار اجرا، توسط حلقه‌ای که ما مشخص کرده‌ایم، تعیین می‌گردد.
 --------------- RESULTS: NBenchSample.DictionaryThroughputTests+AddThroughput_ThroughputMode ---------------
[Counter] AddCounter: Max: 575,654.00 operations, Average: 575,654.00 operations, Min: 575,654.00 operations, StdDev: 0.00 operations
[Counter] AddCounter: Max / s: 7,205,997.59 operations, Average / s: 7,163,894.30 operations, Min / s: 7,075,316.79 operations, StdDev / s: 42,518.20 operations

--------------- RESULTS: NBenchSample.DictionaryThroughputTests+AddThroughput_IterationsMode ---------------
[Counter] AddCounter: Max: 20,000,000.00 operations, Average: 20,000,000.00 operations, Min: 20,000,000.00 operations, StdDev: 0.00 operations
[Counter] AddCounter: Max / s: 7,409,380.61 operations, Average / s: 7,250,991.24 operations, Min / s: 6,880,938.73 operations, StdDev / s: 148,085.19 operations
اگر دقت کنید، کارآیی اندازه گیری شده‌ی در حالت RunMode.Iterations بیشتر است از حالت RunMode.Throughput. چون در حالت RunMode.Throughput، فریم ورک کار اجرای متد را از طریق Reflection انجام می‌دهد. بنابراین بهتر است از حالت RunMode.Iterations، جهت رسیدن به نتایج دقیق‌تری استفاده کرد.
در اینجا برای گزارش دادن، عددهای Average و  Average / s باید مورد استفاده قرار گیرند.