مطالب
معرفی Actor Based Programming و توسعه نرم افزار های مقیاس پذیر و دارای عملیات همزمان بسیار زیاد - قسمت دوم
در  قسمت قبل توضیحاتی راجع به مقدمات Actor Based Programming و کاربرد آن داده شد و چند framework نیز برای توسعه به این روش معرفی گردید. در این قسمت جزئیات بیشتری را از این روش توسعه، ارائه خواهیم داد.
خط تولید کارخانه‌ای را فرض کنید که در آن یک قطعه از ابتدای خط حرکت نموده و کارگران مستقر در خط تولید نیز هر کدام بنا به وظیفه‌ی خود، کاری را بر روی قطعه‌ی مورد نظر انجام می‌دهند؛ به طوریکه در انتهای خط تولید، آن قطعه‌ی اولیه، به یک محصول کامل تبدیل می‌شود.

 ایده‌ی Actor Based نیز هم از همین روش الهام گرفته است. با این تفاوت که بجای کارگران، Thread داریم و بجای قطعه نیز یک پیام یا object و بجای خط تولید نیز خط لوله یا pipeline را داریم. همانطور که در قسمت قبل اشاره کردم، وظیفه‌ی توسعه دهنده در این روش، طراحی یک خط لوله و نوشتن کد مربوط به هر thread است. به همین سادگی!
یعنی تمام پیچیدگی‌های مربوط به concurrency و مسائل فنی توسط یک framework مثل TPL DataFlow یا Akka کنترل و مدیریت می‌شود و توسعه دهنده با تمرکز بر روی مسئله‌ی خود، شروع به طراحی (کانفیگ) خط لوله و نوشتن کد مربوط به هر کدام از thread‌ها می‌نماید.

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

خوب حالا که با مفاهیم خط لوله و اکتور آشنا شدیم، یک مسئله‌ی بسیار ساده را در نظر می‌گیریم و آن را با این روش حل می‌کنیم. فرض کنید یک رشته (string) داریم و می‌خواهیم عملیات زیر را بر روی آن به ترتیب انجام دهیم:

1- فاصله‌های اضافی ابتدا و انتهای رشته حذف شود.

2- اگر رشته یک کلمه‌ای است lowerCase شود.

3- اگر رشته بیش از یک کلمه است، تمام کلمات، به جز کلمه‌ی اول، حذف شوند و سپس مرحله‌ی 2 بر روی آن انجام شود.

4- نتیجه‌ی کار در خروجی نمایش داده شود.

حالا می‌خواهیم انجام هر یک از عملیات فوق را به یک اکتور سپرده و یک خط لوله را برای حل این مسئله طراحی کنیم. در قسمت بعدی به صورت عملی و با TPL DataFlow مایکروسافت این کار را انجام می‌دهیم.

مطالب
SASS #1

SASS چیست؟

SASS مخفف Syntactically Awesome Style Sheets است که توسط آقای Hampton Catlin طراحی و ایجاد شده است و همانند CoffeeScript که پس از کامپایل به جاوااسکریپت تبدیل می‌شد، SASS نیز پس از کامپایل به CSS تبدیل می‌شود. SASS با استفاده از متغیرها، mixins، ارث بری و قوانین تودرتو، CSS را با مهارت زیادی در بهترین حالت تولید می‌کند.

SASS باعث کمتر نوشتن کد CSS، سبب افزایش خوانایی و دستکاری کردن راحتتر و پویای آن می‌شود. این مساله راهی عالی برای نوشتن کدهای CSS کاربردی‌تر است و می‌تواند سرعت گردش کار هر توسعه دهنده و یا طراح وب را افزایش دهد.

وقتی اولین بار SASS عرضه شد، syntax آن تفاوت قابل توجهی با CSS داشت (پسوند فایل‌های آن SASS. است) که به جای نوشتن براکت‌ها، از تورفتگی استفاده می‌شد و دیگر نیازی به نوشتن ";" نبود. البته با عدم استقبال از این syntax مواجه شد و با عرضه‌ی نسخه 3 SASS، (که پسوند فایل‌های آن SCSS. است) syntax آن بسیار شبیه به CSS شد؛ البته با همه‌ی ویژگی‌های SASS.

برای مثال کد CSS زیر را می‌خواهیم به دو روش بنویسیم:

header {
     margin: 0;
     padding: 0;
     color: #fff;
}
با استفاده از روش SCSS. (روش جدید)
$color:  #fff;
header {
    margin: 0;
    padding:0;
    color: $color;
}
با استفاده از روش SASS. (روش قدیم)
$color: #fff
header
   margin: 0
   padding: 0
   color: $color
همانطور که مشاهده می‌کنید برای نوشتن مقدار color از متغیر color$ استفاده کردیم . در ادامه به قابلیت‌های SASS خواهیم پرداخت.

توجه: syntax ایی که در این سری آموزشی با آن کار می‌کنیم SCSS. است.

کامپایل کردن SASS

روش‌های مختلفی برای کامپایل فایل‌های SASS وجود دارند:
  • روش اصلی استفاده از SASS در Ruby است که پس از نصب Ruby و اجرای فرمان SASS ،gem install sass نصب می‌شود و برای کامپایل، اجرای فرمان زیر:
sass myfile.scss myfile.css
  • استفاده از برنامه‌های گرافیکی مانند Hammer , CodeKit و Compass.
  • استفاده از برنامه‌های رایگان مانند libsass که با یک کامپایلر سریع نوشته شده با ++C/C است و همچنین می‌توانید libsass را از طریق NPM با node-sass   نصب کنید.
npm install node-sass
نکته: در صورتیکه می‌خواهید با استفاده از Ruby کار کامپایل را انجام دهید در هنگام نصب Ruby گزینه‌ی "Add Ruby executables to your PATH" را تیک بزنید.

خب سوالی که ممکن است برای شما پیش آمده باشد این است که باید از کدام یک از این روش‌ها را استفاده کنیم؟
بستگی به این دارد که شما چه کاری را می‌خواهید انجام دهید.
  • در صورتیکه بر روی یک پروژه‌ی بزرگ با میزان کد زیاد کار می‌کنید، استفاده از Ruby SASS، کمی کند کار کامپایل را انجام می‌دهد.
  • اگر بخواهید از libsass استفاده کنید، این مسئله وجود دارد که به طور %100 با قابلیت‌های Ruby SASS برابری ندارد.
  • در صورتیکه نمی‌خواهید از command line استفاده کنید، برنامه‌های گرافیکی گزینه‌ای عالی هستند. شما می‌توانید طوری تنظیم کنید که تمامی تغییراتی که در فایل SASS انجام می‌شود، به صورت خودکار کار کامپایل انجام شود.
  • اگر هم فقط می‌خواهید کدی را که نوشته‌اید تست کنید، می‌توانید از ابزارهای آنلاین مانند SassMeister استفاده کنید.
مطالب
OpenCVSharp #13
تشخیص قسمت‌های مشابه تصاویر در OpenCV

در شکل زیر، دو تصویر سمت چپ و راست، اندکی با هم تفاوت دارند و در تصویر سوم، نقاط مشابه یافت شده‌ی توسط OpenCV ترسیم شده‌اند:


کدهای مثال فوق را در ذیل مشاهده می‌کنید:
var img1 = new Mat(@"..\..\Images\left.png", LoadMode.GrayScale);
Cv2.ImShow("Left", img1);
Cv2.WaitKey(1); // do events
 
var img2 = new Mat(@"..\..\Images\right.png", LoadMode.GrayScale);
Cv2.ImShow("Right", img2);
Cv2.WaitKey(1); // do events
 
 
// detecting keypoints
// FastFeatureDetector, StarDetector, SIFT, SURF, ORB, BRISK, MSER, GFTTDetector, DenseFeatureDetector, SimpleBlobDetector
// SURF = Speeded Up Robust Features
var detector = new SURF(hessianThreshold: 400); //SurfFeatureDetector
var keypoints1 = detector.Detect(img1);
var keypoints2 = detector.Detect(img2);
 
// computing descriptors, BRIEF, FREAK
// BRIEF = Binary Robust Independent Elementary Features
var extractor = new BriefDescriptorExtractor();
var descriptors1 = new Mat();
var descriptors2 = new Mat();
extractor.Compute(img1, ref keypoints1, descriptors1);
extractor.Compute(img2, ref keypoints2, descriptors2);
 
// matching descriptors
var matcher = new BFMatcher();
var matches = matcher.Match(descriptors1, descriptors2);
 
// drawing the results
var imgMatches = new Mat();
Cv2.DrawMatches(img1, keypoints1, img2, keypoints2, matches, imgMatches);
Cv2.ImShow("Matches", imgMatches);
Cv2.WaitKey(1); // do events
 
Cv2.WaitKey(0);
 
Cv2.DestroyAllWindows();
img1.Dispose();
img2.Dispose();
در ابتدا نیاز به یک تشخیص دهنده یا Detector داریم. در OpenCVSharp، الگوریتم‌ها و کلاس‌های FastFeatureDetector, StarDetector, SIFT, SURF, ORB, BRISK, MSER, GFTTDetector, DenseFeatureDetector, SimpleBlobDetector برای اینکار قابل استفاده هستند. برای مثال در اینجا از الگوریتم SURF آن استفاده شده‌است.
کار این تشخیص دهنده، تشخیص نقاط کلیدی تصاویر است. برای مثال تشخیص گوشه‌ها، لبه‌ها و غیره.
سپس اطلاعات نواحی اطراف هر نقطه‌ی کلیدی را تحت عنوان descriptors استخراج می‌کنیم.
بعد از محاسبه‌ی نقاط کلیدی هر تصویر، اینبار نیاز است این نقاط را بین دو تصویر با هم مقایسه کرد و مشابه‌ها را یافت. برای مثال الگوریتم BFMatcher یک Brute force matcher است که بر اساس اطلاعات نواحی اطراف هر نقطه‌ی کلیدی، سعی در یافتن نقاط مشابه می‌کند.
پس از یافتن نقاط مشابه، نیاز است بر اساس آن‌ها نگاشتی بین دو تصویر صورت گیرد و مشابه‌ها ترسیم شوند. متد DrawMatches این‌کار را انجام می‌شود.

اگر علاقمند هستید که با ریز جزئیات ریاضی الگوریتم‌های استفاده شده نیز آشنا شوید، سری مطالب descriptors را دنبال نمائید.


کدهای کامل این مثال را از اینجا می‌توانید دریافت کنید.
مطالب
Performance در AngularJS قدم سوم
خیلی خوشحالم که تا این مرحله، این مقاله‌ها را دنبال می‌کنید. در مقالات قبل مسائل ساده و مهمی در بحث Performance مطرح شد. در این مقاله می‌خواهم قدم سوم در بهبود Performance را توضیح دهم که رعایت کردن این مسائل می‌تواند کمک زیادی در بهبود عملکرد برنامه‌های مبتنی بر AngularJS داشته باشد.

scope؟
همه‌ی برنامه نویسان و توسعه دهندگان، یکی از اولین مفاهیمی را که در AngularJS یاد می‌گیرند، scope هست. اما scope چیست؟ به صورت خیلی ساده می‌توان گفت scope مشخص کننده‌ی حوزه متغیر‌ها و توابعی هست که قرار است در View تاثیر داشته باشند. کد زیر را مشاهده کنید:
<div>نام و نام خانوادگی: {{name}}</div>
<div>معدل: {{avg()}}<div>
و کد سمت controller
scope.nums=[19,20,17,16,15,18,19];
scope.name='بهنام محمدی';
scope.avg= function(){
  return scope.nums.reduce(function(previousValue, currentValue) {
      return previousValue + currentValue;
   })/scope.nums.length;
}
و اما خروجی نهایی
نام و نام خانوادگی: بهنام محمدی
معدل:17.71
خوب چون ما در قسمت controller به صورت scope.name و scope.avg عمل کرده‌ایم، می‌توانیم در View به صورت name و avg از این متغیر‌ها استفاده کنیم. در نتیجه اگر ما در controller، به جای scope.name بنویسیم name و یا به جای scope.avg بنویسیم avg به مشکل بر می‌خوریم؛ چون قسمت View ما متغیر‌های داخل scope را در View دخیل می‌کند و متغیر‌های داخل scope توسط Watcher‌ها رصد می‌شود.

خوب سؤال، همه چیز که عالی هست پس مشکل در کجاست؟
مشکل در متغیر scope.nums هست! به کد زیر توجه کنید:
var nums=[19,20,17,16,15,18,19];
scope.name='بهنام محمدی';
scope.avg= function(){
  return nums.reduce(function(previousValue, currentValue) {
      return previousValue + currentValue;
   })/nums.length;
}
فکر کنم متوجه تفاوت این کد با کد بالایی شده‌اید. اما کدام کد درست است؟ یا بهتر بگویم کدام کد بر روی Performance تاثیر مناسبی دارد؟ کد پایینی Performance بالایی دارد. دلیل این موضوع این است وقتی ما از nums در View هیچ استفاده‌ای نمی‌کنیم، بهتر است به صورت var nums تعریف شود. در کد بالایی که این متغیر به صورت scope.nums تعریف شده بود، با اینکه در View استفاده نشده بود، ولی توسط Watcher AngularJS در هر لحظه رصد می‌شود و این کار باعث کندی و کاهش عملکرد AngularJS خواهد شد. بنابراین در کل متغیرهایی را که در View استفاده نمی‌کنید، به صورت var test استفاده نمایید تا Watcher AngularJS این متغیر‌ها را رصد نکند.
امیدوارم از این مقاله لذت برده باشید. منتظر مقاله بعدی من باشید.

مطالب
آشنایی با جنریک‌ها #2
قبل از ادامه آموزش مفاهیم جنریک، در نظر داشتن این نکته ضروری است که مطالبی که در این سری مقالات ارائه می‌شود در سطح مقدماتی است و قصد من آشنا نمودن برنامه نویسانی است که با این مفاهیم ناآشنا هستند ولی با مطالعه این مقاله می‌توانند کدهای تمیزتر و بهتری تولید کنند و همینطور این مفاهیم ساده، پایه‌ای باشد برای فراگیری سایر نکات تکمیلی و پیچیده‌تر جنریک‌ها.

در قسمت قبلی، نحوه تعریف کلاس جنریک شرح داده شد و در سری دوم اشاره‌ای به مفاهیم و نحوه پیاده سازی اینترفیس جنریک می‌پردازیم.
مفهوم اینترفیس جنریک همانند مفهوم اینترفیس در دات نت است. با این تفاوت که برای آن‌ها یک نوع عمومی تعریف می‌شود و نوع آن‌ها در زمان اجرا تعیین خواهد شد و کلاس بر اساس نوع اینترفیس، اینترفیس را پیاده سازی می‌کند. برای درک بهتر به نحوه تعریف اینترفیس جنریک زیر دقت کنید:
public interface IBinaryOperations<T>
{
   T Add(T arg1, T arg2);
   T Subtract(T arg1, T arg2);
   T Multiply(T arg1, T arg2);
   T Divide(T arg1, T arg2);
}
در کد بالا اینترفیسی از نوع جنریک تعریف شده است که دارای چهار متد با چهار خروجی و پارامترهای چنریک می‌باشد که نوع خروجی‌ها و نوع پارامترهای ورودی در زمان استفاده از اینترفیس تعیین می‌شوند که البته در بالا بطور خاص بیان شده است. اینترفیسی داریم که دو ورودی از هر نوعی دریافت می‌کند و چهار عملی اصلی را بر روی آن‌ها انجام داده و خروجی آن‌ها را از همان نوع پارامتر ورودی تولید می‌کند. (بجای اینترفیس‌های مختلف عملیات چهار عمل اصلی برای هر نوع داده (data type)، یک اینترفیس کلی برای تمام data typeها)
در کلاس زیر نحوه پیاده سازی اینترفیس از نوع int را مشاهده می‌کنید که چهار عملی اصلی را برروی داده هایی از نوع int انجام می‌شود و چهار خروجی از نوع int تولید می‌شود.
public class BasicMath : IBinaryOperations<int>
{
   public int Add(int arg1, int arg2)
   { return arg1 + arg2; }
 
   public int Subtract(int arg1, int arg2)
   { return arg1 - arg2; }
 
   public int Multiply(int arg1, int arg2)
   { return arg1 * arg2; }
 
   public int Divide(int arg1, int arg2)
   { return arg1 / arg2; }
}
بعد از پیاده سازی اینترفیس حال نوبت به استفاده از کلاس می‌رسد که زیر نیز نحوه استفاده از کلاس نمایش داده شده است:
static void Main(string[] args)
{
   Console.WriteLine("***** Generic Interfaces *****\n");
   BasicMath m = new BasicMath();
   Console.WriteLine("1 + 1 = {0}", m.Add(1, 1));
   Console.ReadLine();
}
و در صورتیکه بخواهید کلاسی چهار عمل اصلی را بر روی نوع داده double انجام دهد کافیست کلاسی اینترفیس نوع double را پیاده سازی کرده باشد. مانند کد زیر:
public class BasicMath : IBinaryOperations<double>
{
   public double Add(double arg1, double arg2)
   { return arg1 + arg2; }
   ...
}
برداشتی آزاد از این مقاله.
مطالب
تفاوت AngularJS با KnockoutJS
با پیشرفت HTML 5 و پدید آمدن چارچوب‌های مختلف JavaScript توسعه‌ی نرم افزار‌های تک صفحه ای تحت وب (Single Page Applications) محبوب شده است. 
اخیرا مطالب خوبی در رابطه با AngularJS در وبسایت جاری منتشر شده است. KnockoutJS توسط Microsoft معرفی شد و در قالب پیشفرض پروژه‌های SPA قرار گرفت ، بنابراین احتمالا این سوال برای افرادی مطرح شده است که تفاوت بین KnockoutJS و AngularJS چیست ؟ 
می توان پاسخ داد این مقایسه ممکن نیست. 
KnockoutJS : یک پیاده سازی مستقل JavaScript از الگوی MVVM با امکانات Databinding می‌باشد. Knokcout یک کتابخانه‌ی Databinding است نه یک کتاب خانه‌ی SPA
AngularJS : طبق معرفی در این مطلب AngularJS فریم ورکی متن باز و نوشته شده به زبان جاوا اسکریپت است. هدف از به وجود آمدن این فریم ورک، توسعه هر چه ساده‌تر SPA‌ها با الگوی طراحی MVC و تست پذیری هر چه آسان‌تر آن‌ها است. این فریم ورک توسط یکی از محققان Google در سال 2009 به وجود آمد. بعد‌ها این فریم ورک تحت مجوز MIT به صورت متن باز در آمد و اکنون گوگل آن را حمایت می‌کند و توسط هزاران توسعه دهنده در سرتاسر دنیا، توسعه داده می‌شود. 

بنابراین شاید بهتر باشد ذکر شود AngularJS یک Presentation Framework مخصوص برنامه‌های وب تک صفحه ای می‌باشد در حالی که KnockoutJS کتاب خانه ای با تمرکز بر Databinding می‌باشد ، بنابراین مقایسه‌ی این‌ها چندان صحیح نیست.

اگر قصد بر بررسی گزینه‌های دیگر در کنار Angular باشد ، می‌توان از Durandal نام برد. Durandal یک چارچوب SPA می‌باشد ، این چارچوب بر فراز jQuery ، RequireJS و Knockout توسعه پیدا کرده است. (سابقا برای routing از SammyJS استفاده می‌کرد که در نسخه‌های اخیر از موتور خودش استفاده می‌کند.)

Durandal از Knockout جهت Databinding و از RequireJS برای مدیریت وابستگی‌ها استفاده می‌کند.
Angular همه‌ی امکانات بالا را مستقل پیاده سازی کرده و حتی نیازی به jQuery ندارد. اگر jQuery وجود داشته باشد Angular از آن استفاده می‌کند در غیر این صورت از jQuery Lite یا jqLite استفاده می‌کند. jqLite پیاده سازی توابع متداول jQuery برای دستکاری DOM می‌باشد. اطلاعات بیشتر در اینجا

بنابراین با استفاده تنها از KnockoutJS نمی‌توان یک برنامه‌ی کامل SPA توسعه داد ، در کنار آن نیاز به کتابخانه‌های دیگری مثل jQuery برای مدیریت درخواست‌های  AJAX و استفاده از دیگر API‌ها ، Sammy برای routing و RequireJS برای مدیریت وابستگی‌ها می‌باشد.

در Knockout و در نتیجه Durandal عمل Databinding به این صورت است :
// JavaScript
var vm = {
    firstName = ko.observable('John')
};
ko.applyBindings(vm);
<!-- HTML -->
<input data-bind="value:firstName"/>
در Angular :
// JavaScript
// Inside of a personController
this.firstName = 'John';
در Angular همچنین از یک روش Controller As استفاده می‌شود :
<!-- HTML -->
<div ng-controller="personController as vm">
    <input ng-model="vm.firstName"/>
</div>
اگر تنها نیاز به یک کتابخانه‌ی Databinding باشد ، Knockout گزینه‌ی مناسبی است ، به خوبی از عمل مقید سازی داده‌ها پشتیبانی می‌کند و Syntax خوش دستی دارد اما اگر نیاز به چارچوبی برای توسعه‌ی پروژه‌های SPA می‌باشد می‌توان از Angular یا Durandal استفاده کرد. 
مقایسه‌ی Knockout با Angular همانند مقایسه‌ی موتور بنز با ماشین پورشه می‌باشد. 



مطالب
آشنایی با Directive ها در AngularJs
اگر مطالعه ای اجمالی درباره مزیت‌ها و قدرت‌های فریم ورک Angular داشته باشید یکی از مواردی که بسیار جلب توجه می‌کند مبحث Directive‌ها است. به کمک Directive‌ها در Angular می‌توانید کد‌های HTML خود را توسعه دهید. این توسعه علاوه بر تعریف تگ‌های جدید، شامل توسعه کلاس‌ها و همچنین ویژگی‌های تگ‌های HTML نیز خواهد بود. کد‌های HTML شما بسیار خواناتر و از طرفی با قابلیت استفاده مجدد می‌شود. البته این پست فقط شروع به کار در این مقوله است زیرا مبحث Directive‌ها بسیار گسترده‌تر از آن است که بتوان مطالب آن را در  یک مقاله گنجاند.
برای شروع یک فایل جاوا اسکریپ ایجاد کرده و در ابتدای آن یک ماژول تعریف کنید:
var app = angular.module('myApp', []);
در این جا نام ماژول را myApp انتخاب کردم. حال یک Directive به نام angry (نام دیرکتیو‌ها را با حروف کوچک آغاز کنید )به صورت زیر ایجاد می‌کنیم:
app.directive('angry', function () {
    return {
        restrict: 'E',
        template: '<div style="color:red"> I am angry!</div>'
    }
})
 تابع سازنده Directive مورد نظر که یک آبجکت را برگشت می‌دهد شامل خواص زیر می‌باشد:
restrict: که چهار مقدار E و A و C و M را می‌پذیرد که به EACM نیز معروف هستند.
E: زمانی که قصد داشته باشیم یک المان جدید بسازیم از E به معنای element در restrict استفاده می‌کنیم(<my-directive></my-directive> 
 A: زمانی که قصد داشته باشیم Directive مورد نظر به عنوان Attribute در تگ‌ها استفاده شود از A به معنای Attribute در restrict استفاده می‌شود(<div my-directive="exp"></div> 
C: از C نیز برای تعریف Directive به عنوان مقادیر ویژگی کلاس استفاده می‌کنیم(<div class="my-directive: exp "></div> 
M: حالت M  نیز برای استفاده Directive در کامنت‌ها است(<!-- directive: my-directive exp -->  ).
در ادامه یک Directive  دیگر به نام happy می‌سازیم:
app.directive('happy', function () {
    return {
        restrict: 'A',
        template: '<div style="color:blue"> I am happy!</div>'
    };
})
تفاوت اصلی بین این دو Directive در نوع restrict آن‌ها می‌باشد. برای استفاده از این Directive‌ها در View می‌توان به صورت زیر عمل نمود:
<script type="text/javascript" src="~/scripts/Modules/module1.js"></script>

<div ng-app="myApp">
    <angry></angry>
    <div happy></div>
</div>
همان طور که می‌بینید دستور Directive اول که را با restrict از نوع E است می‌توان به عنوان یک تگ جدید استفاده کرد. دستور happy به عنوان ویژگی تگ div مورد استفاده قرار می‌گیرد(به دلیل اینکه restrict آن از نوع A است) که در نهایت خروجی ساده مثال بالا به صورت زیر خواهد بود:



ادامه دارد...
مطالب
ایجاد لینک با یک تصویر بوسیله Html Helper
با Html Helper ما میتوانیم لینک‌های متن دار را ایجاد نماییم. شاید گاهی پیش آید که بجای لینک‌های متنی، از تصویر بجای لینک بخواهید استفاده نمایید. می‌توان هر زمانی، لینکی را که حاوی یک تصویر باشد، ایجاد کنید. اما با Asp.net MVC یکی از راه‌های مناسب برای انجام این کار استفاده از Extension methods است که از تکرار کد نویسی نیز جلو گیری می‌نماید.
همان طور که در کد زیر مشاهد می‌نمایید، این کد تشکیل شده است از نوشته لینک و نام اکشن متد و نام کنترلر آن، همراه با آی دی و تعریف css. کاری که قرار است صورت گیرد همانند ActionLink می‌باشد، با این تفاوت که تصویری هم به لینک ما اضافه خواهد شد:
 @Html.ActionLink("Text to display", "ActionNameHere", "ControllerNameHere", new { id = 123 }, new{@class="myClass"})
برای نوشتن این متد جهت تولید لینک‌هایی به همراه تصویر، از کد‌های زیر استفاده می‌کنیم:
public MvcHtmlString ActionImage(this HtmlHelper htmlHelper,
   string controller,
   string action,
   object routeValues,
   string imagePath,
   string alternateText = "",
   object htmlAttributes = null)
{
  var anchorBuilder = new TagBuilder("a");
  var url = new UrlHelper(HtmlHelper.ViewContext.RequestContext);
  anchorBuilder.MergeAttribute("href",url.Action(action,controller,routeValues));
  var imgBuilder = new TagBuilder("img");
  imgBuilder.MergeAttribute("src", url.Content(imagePath));
  imgBuilder.MergeAttribute("alt", alternateText);
  var attributes = (IDictionary<string, object>) HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
  imgBuilder.MergeAttributes(attributes);
  string imgHtml = imgBuilder.ToString(TagRenderMode.SelfClosing);
  anchorBuilder.InnerHtml = imgHtml;
  return MvcHtmlString.Create(anchorBuilder.ToString());
}
اولین پارامتر اجازه گسترش HtmlHelper را می‌دهد و توسط آن می‌توان متد‌های جدید خود را با کلمه کلیدی @Html شروع کنید.
4 پارامتر بعدی، پارامترهای ضروری هستند. یکی  controller، پس از آن Action  routeValues و سپس آدرس تصویر است. در نهایت، ما می‌توانیم در صورت نیاز متن جایگزین و ویژگی‌های اضافی متنی را نیز مشخص نماییم.
 در رابطه با توضیحات مربوط به بدنه متد: ابتدا لینک‌ها را ایجاد خواهد کرد با استفاده از RequestContext و UrlHelper. سپس بخش ساخت تصویر و اضافه کردن آن به لینک است. برای استفاده از میتوان از کد زیر استفاده نمود:
 @Html.ActionImage("Workout", "Delete", new { id = @workout.Id }, "/images/bluetrash.png", "Delete", new { id="deletebutton"})

در شکل بالا خروجی HTML تولید شده را  مشاهد می‌نمایید.
مطالب
استفاده از OfType یا Cast در Linq
تقریبا تمام توسعه دهندگان دات نت با تکنولوژی Linq  و Lambda Expression‌ها آشنایی دارند. همان طور که می‌دانیم Extension Method‌های موجود در فضای نام System.Linq فقط بر روی مجموعه ای از داده‌ها که اینترفیس IEnumerable<t> که در فضای نام System.Collections.Generic قرار دارد را پیاده سازی کرده باشند قابل اجرا هستند. مجموعه داده‌های جنریک فقط قابلیت نگهداری از یک نوع داده که به عنوان پارامتر T برای این مجموعه تعریف می‌شود را داراست.
نکته: البته در مجموعه هایی نظیر Dictionary یا سایر Collection‌ها امکان تعریف چند نوع داده به عنوان پارامتر وجود دارد. نکته مهم این است که داده‌های استفاده شده در این مجموعه ها، حتما باید از نوع پارامتر تعریف شده باشند.
اگر در یک مجموعه داده قصد داشته باشیم که داده هایی با نوع مختلف را ذخیره کنیم و در جای مناسب آن‌ها را بازیابی کرده و در برنامه استفاده نماییم چه باید کرد. به عنوان یک پیشنهاد می‌توان از مجموعه‌های موجود در فضای نام System.Collection بهره بگیریم. اما همان طور که واضح است این مجموعه از  داده‌ها به صورت جنریک نمی‌باشند و امکان استفاده از Query‌های Linq در آن‌ها به صورت معمول امکان پذیر نیست. برای حل این مشکل در دات نت دو متد تعبیه شده است که وظیفه آن تبدیل این مجموعه از داده‌ها به مجموعه ای است که بتوان بر روی آن‌ها Query‌های از جنس Linq یا Lambda Expression را اجرا کرد.
  • Cast
  • OfType
#مثال 1
فرض کنید یک مجموعه مثل زیر داریم:
 ArrayList myList = new ArrayList();

  myList.Add( "Value1" );
  myList.Add( "Value2" );
  myList.Add( "Value3" );

  var myCollection = myList.Cast<string>();
در مثال بالا یک Collection از نوع ArrayList ایجاد کردیم که در فضای نام System.Collection قرار دارد. شما در این مجموعه می‌توانید از هر نوع داده ای که مد نظرتان است استفاده کنید. با استفاده از اپراتور Cast توانستیم این مجموعه را به نوع مورد نظر خودمان تبدیل کنیم و در نهایت به یک مجموعه از IEnumerable<T> برسیم. حال امکان استفاده از تمام متد‌های Linq امکان پذیر است.
#مثال دوم:
   ArrayList myList = new ArrayList();

    myList.Add( "Value1" );
    myList.Add( 10 );
    myList.Add( 10.2 );

   var myCollection = myList.Cast<string>();
در مثال بالا در خط آخر با یک runtime Error مواجه خواهیم شد. دلیلش هم این است که ما از در ArrayList خود داده‌های غیر از string نظیر int یا double داریم. درنتیجه هنگام تبدیل داده‌های int یا double به string یک Exception رخ خواهد داد. در این گونه موارد که در لیست مورد نظر داده‌های غیر هم نوع وجود دارد باید متد OfType را جایگزین کنیم.
ArrayList myList = new ArrayList();

myList.Add( "Value1" );
myList.Add( 10 );
myList.Add( 10.2 );
           
 var doubleNumber = myList.OfType<double>().Single();
 var integerNumber = myList.OfType<int>().Single();
 var stringValue = myList.OfType<string>().Single();
تفاوت بین متد Cast و OfType در این است که متد Cast سعی دارد تمام داده‌های موجود در مجموعه را به نوع مورد نظر تبدیل کند ولی متد OfType فقط داده‌های از نوع مشخص شده را برگشت خواهد داد. حتی اگر هیچ آیتمی از نوع مورد نظر در این مجموعه نباشد یک مجموعه بدون هیچ داده ای برگشت داده می‌شود.
مطالب
آشنایی با Implicit Casting و Explicit Casting
همه ما به نحوی در پروژه‌های خود مجبور به تبدیل انوع داده شده ایم و یک نوع از داده یا Object رو به نوع دیگری از داده یا Object تبدیل کرده ایم. در این پست دو روش دیگر برای تبدیل انواع داده‌ها بررسی میکنیم. برای شروع دو کلاس زیر رو در نظر بگیرید.
#1کلاس Book
    public class Book
    {
        public int Code { get; set; }
        public string Title { get; set; }
        public string Category { get; set; }        
    }
#2کلاس NoteBook
    public class NoteBook
    {
        public int Code { get; set; }
        public string Title { get; set; }        
    }
این دو کلاس هیچ ارتباطی با هم ندارند در نتیجه امکان تبدیل این دو نوع وجود ندارد یعنی اجرای هر دو دستور زیر باعث ایجاد خطای کامپایلری می‌شود.
        static void Main( string[] args )
        {
            Book book = new Book() 
            {
                Code = 1,
                Title = "Book1",
                Category = "Default"
            };

            NoteBook noteBook = new NoteBook();

            noteBook = (NoteBook)book;//Compile error
            noteBook = book as NoteBook;//Compile error
        }
برای حل این مشکل و تبدیل این دو نوع از Object‌ها می‌تونیم از دو نوع ImplicitCasting و Explicit Casting استفاده کنیم.
#Explicit Casting
public class Book
    {
        public int Code { get; set; }
        public string Title { get; set; }
        public string Category { get; set; }

        public static explicit operator NoteBook( Book book )
        {
            return new NoteBook()
            {
                Code = book.Code,
                Title = book.Title
            };
        }
    }
در Explicit یک Operator به صورت Explicit تعریف می‌کنیم که ورودی اون از نوع خود کلاس book و خروجی اون از نوع مورد دلخواه است. Converter مورد نظر رو در بدنه این Operator می‌نویسیم. حالا به راحتی دستور زیر کامپایل می‌شود.
static void Main( string[] args )
        {
            Book book = new Book() 
            {
                Code = 1,
                Title = "Book1",
                Category = "Default"
            };

            NoteBook noteBook = new NoteBook();

            noteBook = (NoteBook)book;//Correct  
        }

در بالا مشاهده می‌کنید که حتما باید به طور صریح عملیات Cast رو انجام دهیددر غیر این صورت همچنان خطا خواهید داشت. اما می‌توان این مراحل رو هم نادیده گرفت و تبدیل رو به صورت Implicit انجام داد.

#Implicit Casting

public class Book
    {
        public int Code { get; set; }
        public string Title { get; set; }
        public string Category { get; set; }

        public static implicit operator NoteBook( Book book )
        {
            return new NoteBook()
            {
                Code = book.Code,
                Title = book.Title
            };
        }
    }
تنها تفاوت این روش با روش قبلی، در نوع تعریف operator است. بعد از تعریف نوع استفاده به صورت زیر خواهد بود.

static void Main( string[] args )
        {
            Book book = new Book() 
            {
                Code = 1,
                Title = "Book1",
                Category = "Default"
            };

            NoteBook noteBook = new NoteBook();

            noteBook = book;//Correct  
        }
در این روش نیاز به ذکر نوع Object برای Cast نیست و Object مورد نظر به راحتی به نوع داده قبل از اپراتور = تبدیل می‌شود.