مطالب
جلوگیری از Brute Force Attack
یکی از حملات رایج که توسعه دهندگان با آن روبرو هستند، Brute-Force Attack میباشد. در این حملات برای کشف رمزعبور کاربران، هر ترکیب احتمالی از حروف، اعداد و نمادها را استفاده میکنند تا یک ترکیب صحیح را بدست آورند. اگر وب سایت شما نیاز به احراز هویت دارد، شما یک هدف مناسب برای حملات Brute-Force هستید! یک هکر میتواند رمزعبور را از این طریق بدست آورد؛ اما یافتن آن شاید سالها طول بکشد که بستگی به طول رمز و پیچیدگی آن، ممکن است چندین سال طول بکشد. اما یک حمله Brute-Force میتواند سریع‌تر انجام شود، میتواند از فرهنگ لغت استفاده کند و یا کلمات فرهنگ لغت را کمی تغییر دهد، زیرا بیشتر افراد بجای یک کلمه‌ی عبور تصادفی و پیچیده، از آن کلمات استفاده میکنند. به این حملات dictionary attacks یا hybrid brute-force attacks نیز گفته میشود. این حملات حساب‌های کاربران را در معرض خطر قرار میدهد و باعث افزایش ترافیک غیرضروری سایت شما میشود.

هکرها از ابزارهای گسترده‌ای که لیست کلمات و قواعد هوشمندانه‌ای را دارند استفاده میکنند تا به طور هوشمندانه و به طور خودکار، کلمه‌های عبور کاربران را حدس بزنند. اگرچه شناسایی چنین حملاتی آسان است، اما جلوگیری از آن کار آسانی نیست. به طور مثال برخی از ابزارهای HTTP brute-force میتوانند درخواست‌ها را از طریق پروکسی‌های باز سرور انجام دهند و از آنجا که هر درخواست از یک IP متفاوت میرسد، نمیتوانید با مسدود کردن IP، حملات را مسدود کنید. حتی برخی از ابزارها برای هر بار درخواست، یک نام کاربری و یک کلمه عبور را امتحان میکنند و شما نمیتوانید هر حساب کاربری را برای یک بار عملیات ناموفق مسدود کنید.


مسدود کردن حساب‌ها

بدیهی‌ترین راه برای جلوگیری از این حملات، مسدود کردن حساب‌ها پس از تعداد مشخصی تلاش ناموفق است. مسدود شدن حساب‌ها میتواند مدت زمان خاصی داشته باشد و یا اینکه حساب‌ها باید توسط ادمین سایت فعال شوند. با این وجود، مسدود کردن حساب‌ها همیشه بهترین راه برای جلوگیری از این حملات نیست؛ زیرا شخصی میتواند به راحتی از قوانین سوء استفاده کرده و تعداد زیادی از حساب‌ها را مسدود کند. برخی از مشکلات مربوط به این راه عبارت اند از:
  • یک مهاجم میتواند تعداد زیادی از حساب‌ها را مسدود کند.
  • به دلیل اینکه شما نمیتوانید حسابی را که وجود ندارد، مسدود کنید و فقط حساب‌های معتبر قفل میشوند، یک مهاجم با استفاده از پاسخ خطای مربوط به مسدود شدن حساب کاربری میتواند از اینکار برای برداشتن نام کاربری استفاده کند.
  • یک مهاجم میتواند با مسدود کردن تعداد زیادی از حساب‌ها و جاری شدن تماس‌های پشتیبانی برای بازیابی حساب، باعث انحراف آنها شود.
  • یک مهاجم میتواند به طور مداوم یک حساب کاربری را مسدود کند، حتی چند ثانیه بعد از آنکه ادمین سایت آن حساب را فعال کند، مجددا به مسدود کردن آن اقدام کند.
  • مسدود کردن حساب‌ها برای حملاتی که کند هستند و هر ساعت فقط چند رمز عبور را امتحان میکنند، بی تاثیر است.
  • مسدود کردن حساب‌ها در برابر حملاتی که یک رمز عبور را در برابر لیستی از نام کاربری امتحان میکنند، بی تاثیر است
  • مسدود کردن حساب‌ها در برابر حملاتی که از لیستی از کلمه عبور/نام کاربری استفاده میکنند و در اولین بار به طور صحیح حدس میزنند بی تاثیر است.

مسدود کردن حساب‌ها  گاهی اوقات تاثیرگذار است؛ اما در محیط‌های کنترل شده. با این حال در بیشتر موارد مسدود کردن حساب‌ها برای متوقف کردن حملات brute-force کافی نیست. به عنوان مثال یک سایت حراجی را در نظر بگیرید که چندین داوطلب برای یک کالا در حال مسابقه هستند. اگر وبسایت حراجی حساب‌ها را مسدود کند، یک پیشنهاد دهنده میتواند در لحظات آخر نسبت به مسدود کردن حساب‌های دیگران اقدام کند و مانع از ارائه هرگونه پیشنهادی شود و خود برنده شود. یک مهاجم میتواند از همین تکنیک برای مسدود کردن معاملات حساس مالی و ... اقدام کند.


اقدامات متقابل

همانطور که توضیخ داده شد، مسدود کردن حساب‌ها یک راه کامل برای مقابله با این حملات نیست. اما ترفندهای دیگری نیز برای مقابله با این حملات وجود دارند. از آنجا که موفقیت این حملات به زمان بستگی دارد، یک راه حل آسان، تزریق مکث‌های تصادفی هنگام چک کردن رمز عبور است. افزودن مکث حتی چند ثانیه‌ای میتواند یک حمله را بسیار کند نماید؛ اما بیشتر کاربران را هنگام ورود به سایت، ناراحت نمیکند. توجه داشته باشید اگرچه اضافه کردن تاخیر میتواند یک حمله single-thread را کند، کند اما اگر مهاجم چندین درخواست را همزمان ارسال کند، کمتر موثر است.

راه حل دیگر مسدود کردن یک IP با چند عملیات ناموفق است. اما مشکل این راه حل آن است که شما سهوا گروه‌هایی از کاربران را بلاک میکنید؛ مانند بلاک کردن یک پراکسی سرور که توسط یک ISP استفاده میشود. مشکل دیگر این راه حل استفاده‌ی بسیاری از ابزارها از لیستی از پراکسی‌ها است و با هر IP، دو یا سه درخواست را ارسال میکنند و سپس به دنبال بعدی می‌روند. یک مهاجم میتواند به این طریق به راحتی فرآیند مسدود کردن IP را دور بزند. بیشتر سایت‌ها حساب‌ها را بعد از یک عملیات ناموفق، مسدود نخواهند کرد؛ به همین دلیل یک مهاجم میتواند از هر پراکسی، دو یا سه درخواست را امتحان کند. یک هکر با داشتن لیستی از 1000 پراکسی میتواند 2000 یا 3000  کلمه عبور را امتحان کند؛ بدون مسدود شدن حساب‌ها.

 یک راه حل ساده در عین حال موثر آن است که رفتار وب سایت خود را برای پاسخ به عملیات ناموفق ورود به سایت، درست طراحی نکنید. برای مثال اکثر وب سایت‌ها کد "HTTP 401 error" را برای کلمه عبور اشتباه میفرستند. اگرچه بعضی وب سایت‌ها کد "HTTP 200 SUCCESS" را برمیگردانند، اما کاربر را به صفحه‌ای هدایت میکند و توضیح میدهد که رمز عبور را اشتباه وارد کرده است، این کار برخی سیستم‌ها را فریب می‌دهد اما دور زدن آن نیز راحت است. یک راه حل بهتر آن است که هر بار از پیام‌های خطای مختلفی استفاده کنید و یا گاهی به کاربر اجازه رفتن به یک صفحه را بدهید و دوباره کاربر را وادار به وارد کردن رمز عبور نمایید.

بعضی از ابزارها این امکان را دارند تا مهاجم یک رشته را وارد کند تا به دنبال آن باشند که نشان میدهد عملیات ورود ناموفق بوده است. به عنوان مثال اگر صفحه‌ای شامل عبارت "Bad username or password" باشد، به معنای آن است که عملیات ناموفق بوده است و نام کاربری و یا کلمه‌ی عبور بعدی را امتحان میکند. یک راه ساده برای مقابله با این راه این است که از عبارت‌هایی استفاده کنیم که در هنگام ورود موفق استفاده میشوند.

بعد از دو یا چند تلاش ناموفق، کاربر را وادار به پاسخ دادن به یک سؤال مخفی کنید. این کار نه تنها باعث اختلال در حملات خودکار میشود بلکه از دسترسی فرد مهاجم جلوگیری میکند؛ حتی اگر نام کاربری و رمز عبور را درست وارد کرده باشد.

سایر تکنیک هایی که میتوانید در نظر بگیرید عبارتند از:
  • برای کاربران مهم که میخواهند از حساب خود در مقابل این نوع حملات جلوگیری کنند، به آنها این امکان را  بدهید که بتوانند فقط از IP خاصی وارد سیستم شوند.
  • برای جلوگیری از حملات خودکار، از captcha استفاده کنید.
  • بجای قفل کردن حساب کاربری، آنرا در حالت قفل با دسترسی محدود قرار دهید.

هکرها اغلب میتوانند بسیاری از تکنیک‌ها را به تنهایی دور بزنند. اما با ترکیب چندین حالت میتوانید این حملات را به میزان قابل توجهی کاهش دهید. اگرچه جلوگیری کامل از این حملات سخت است، اما تشخیص آن آسان است؛ زیرا با هربار ورود ناموفق، یک رکورد با کد HTTP 401 در لاگ‌های سرور ثبت میشود. این مهم است که لاگ‌های سرور خود را برای این نوع حملات نظارت کنید در شرایط خاص. کد 200 به آن معناست که مهاجم یک رمز عبور معتبر را پیدا کرده است.

شرایطی که میتوانند حملات brute-force یا سوء استفاده از یک حساب را نشان دهند:
  • تعداد زیادی ورود ناموفق از یک IP
  • تلاش برای ورود به سایت با چند نام کاربری از طرف یک IP
  • تلاش برای ورود به یک حساب کاربری از طرف چندین IP
  • تلاش برای ورود، با وارد کردن نام کاربری و کلمه‌ی عبور، به ترتیب حروف الفبا
  • تلاش برای ورود، با نام کاربری یا کلمات عبوری مانند ownsyou,washere,zealots ,hacksyou یا مشابه آنها که هکرها معمولا از آنها استفاده میکنند

متوقف کردن این حملات دشوار است؛ اما با طراحی دقیق و اقدامات متقابل متعدد، می‌توانید میزان قرار گرفتن در معرض این حملات را محدود کنید. درنهایت، بهترین راه جلوگیری این است که کاربران از قوانین اصلی رمزهای عبور قوی استفاده کنند؛ برای مثال از رمزهای عبور طولانی غیرقابل پیش بینی، اجتناب از کلمات فرهنگ لغت، جلوگیری از استفاده مجدد از گذرواژه‌ها و تغییر گذرواژه‌ها به طور منظم.   
نظرات نظرسنجی‌ها
با توجه به امکانات جدید Razor Components، آیا در آینده از SPA frameworks استفاده میکنید؟
این فناوری مانند این هست که عنوان کنید از جاوا اسکریپت خسته شدم و الان می‌خوام با سیلورلایت کار کنم. نه پختگی فریم ورک‌های تک صفحه‌ای رو داره، نه معلوم هست که در آینده پشتیبانی میشه. دست آخر باز هم برای یکسری از کارهای پیشرفته مجبور میشید به ترکیبی از جی‌کوئری و کدهای فعلی برسید. دقیقا همون مشکلی که با ام وی سی وجود داره. برای ساخت یک فرم ساده فراتر از عالی هست. اما زمانیکه مجبور شدی کمی رابط کاربری پیچیده‌تری رو طراحی کنی، می‌رسی به یک ترکیب نافرم جاوا اسکریپت و کدهای Razor در یک صفحه که تمام شعار آزمون پذیری سیستم رو زیر سؤال می‌بره. فریم ورک‌های تک صفحه‌ای به لطف تایپ‌اسکریپت این مشکل رو حل کردن و می‌تونی یک لایه رابط کاربری بسیار پیچیده و همچنین قابل نگهداری و آزمایش رو توسعه بدی. 
بازخوردهای پروژه‌ها
ایجاد فاکتور فروش
با سلام، من یک فاکتور فروش به صورت زیر می‌خواستم طراحی کنم

قسمت ردیف ، توضیحات ،شماره فیش ساده هستند ولی چگونه می‌توانم قسمت مبلغ را به این صورت طراحی کنم؟

ممنون
نظرات اشتراک‌ها
چگونگی نمایش 10 سایت پر بازدید در IE 5
جالب بود. با اینکه بسیار برای موضوع سازگاری نرم افزار تحت وب با مرورگرهای گوناگون ارزش قائلم ولی به عقیده من با توجه به جمیع جهات در حال حاضر بهتر است برخی مرورگرهای قدیمی حتی تا IE8 و همین طور ورژن قدیمی سایر مرورگرها توسط توسعه دهندگان پشتیبانی نشود و رفتار مناسبی از سوی نرم افزار مانند نمایش هشدار بروزرسانی مرورگر به همراه اطلاعات کافی از علت هشدار و لینک دانلود مرورگر جدید در نظر گرفته شود. در حال حاضر وقت صرفه شده برای IE6 و ... بهتر است صرف سازگاری و ارائه سرویس بهتر برای دیوایس‌های موبایل گردد. با توجه به سیاست کاری برخی وب سایت‌های مطرح اکنون امکان عملی این مورد بهتر فراهم شده است. همچنین در این صورت امکان بهره برداری از بسیاری امکانات جدید دنیای وب با هزینه کمتر فراهم می‌گردد که انصاف نیست کاربران را از آن محروم کنیم.
نظرات مطالب
EF Code First #2

سلام

من از ابزار Power tools جهت استخراج Contex از دیتابیس موجود استفاده نکردم بلکه از Ado.net data model خود ویژوال استدیو اما مدلی که به من میده خیلی شلوغ و پیچیده است و قابل استفاده نیست و این درحالی است که من یک جدول ساده بدون هیچ گونه ریلیشن و یا روابط پیچیده را استفاده کردم !

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

از کجا شروع کنیم
برای نوشتن پلاگین یک تابع با نام خاصیتی جدید را به jQuery.fn اضافه می‌نماییم.
jQuery.fn.myPlugin = function() {
//محتویات پلاگین را اینجا می‌نویسیم
};
اما، برای اینکه بتوانیم از میانبر $ در پلاگین استفاده نماییم و تداخلی با سایر کتابخانه‌ها نداشته باشد، از الگوی (IIFE (Immediately Invoked Function Expression D به صورت زیر استفاده می‌نماییم:
(function( $ ) {
  $.fn.myPlugin = function() {
  //محتویات پلاگین را اینجا می‌نویسیم
    };
})( jQuery );

محتوای پلاگین
حال می‌توانیم در تابع، کدهای پلاگین خود را بنویسیم. برای دسترسی به شیء پاس داده شده به پلاگین، از کلمه کلیدی this استفاده کرده و لازم نیست از (this)$ استفاده نماییم. در زیر یک پلاگین ساده تهیه شده است که با رفتن ماوس بر روی یک متن، خطی زیر آن می‌کشد:
(function($){
    $.fn.underline= function() {
        this.hover(function(){
            $(this).css( { text-decoration : underline })
        }, function(){
            $(this).css( { text-decoration : none } )
        });
    };
})(jQuery);
 
$("p").underline();
پلاگین بالا مقدار یا شیء ایی را بر نمی‌گرداند؛ اما اگر بخواهیم مقداری را برگردانیم از return استفاده می‌نماییم:
(function( $ ){

  $.fn.maxHeight = function() {
  
    var max = 0;

    this.each(function() {
      max = Math.max( max, $(this).height() );
    });

    return max;
  };
})( jQuery );
var tallest = $('div').maxHeight(); // بیشترین ارتفاع عنصر را برمی گرداند

حفظ خاصیت زنجیره‌ای پلاگین ها
در مثال بالا یک مقدار عددی برگردانده شده است؛ اما برای اینکه بتوانیم بصورت زنجیر وار خروجی پلاگین را به تابع یا هر پالاگین دیگری پاس دهیم از تابع each بصورت زیر استفاده می‌نماییم:
(function( $ ){

  $.fn.lockDimensions = function( type ) {  

    return this.each(function() {

      var $this = $(this);

      if ( !type || type == 'width' ) {
        $this.width( $this.width() );
      }

      if ( !type || type == 'height' ) {
        $this.height( $this.height() );
      }

    });

  };
})( jQuery );
$('div').lockDimensions('width').css('color', 'red');
در پلاگین بالا با از تابع each برای روی this و برگرداندن آن با return برای حفظ خاصیت زنجیره‌ای پلاگین استفاده می‌نماییم. در تابع each می‌بایست از (this)$ برای انجام عملیات بر روی شیء پاس داده شده استفاده کنیم. بدین صورت بعد از صدا زدن پلاگین، دوباره می‌توانیم از هر پلاگین یا تابع جی کوئری دیگری بر روی خروجی استفاده نماییم.

پیش فرض‌ها و تنظیمات
در پلاگین‌های پیشرفته‌تر می‌توانیم تنظیمات پیش فرضی را برای پلاگین در نظر بگیریم و این تنظیمات را به عنوان پارامتر ورودی از کاربر دریافت نماییم. جی کوئری دارای تابعی به نام extend است که امکان گسترش و ترکیب دو شیء را امکان پذیر می‌سازد به مثال زیر توجه نمایید:
(function( $ ){

  $.fn.tooltip = function( options ) {  

    var settings = $.extend( {
      'location'         : 'top',
      'background-color' : 'blue'
    }, options);

    return this.each(function() {        

      // Tooltip plugin code here

    });

  };
})( jQuery );
$('div').tooltip({
  'location' : 'left'
});
در این مثال، شیء settings با دو خاصیت location و background-color تعریف شده که با شیء options که از ورودی پلاگین دریافت نموده‌ایم با استفاده از تابع extend ترکیب شده است. خاصیت‌های که تعیین نشده باشند با مقادیر پیش فرض آن‌ها تکمیل می‌گردد.
ادامه دارد...
مطالب
الگوی طراحی Null Object

هنگامیکه درحال طراحی کلاس‌هایی هستیم که وابستگی‌هایی دارند، ممکن است با شرایطی مواجه شویم که به این وابستگی‌ها نیاز نباشد و یا به رفتار عادی بعضی از وابستگی‌ها نیاز نداشته باشیم. شاید راهی که در این مواقع به ذهن برسد این باشد که بجای شیء واقعی وابستگی موردنظر، از یک شیء Null Reference استفاده کنیم. ولی استفاده از این روش کدهایمان را پیچیده خواهد کرد؛ چون هر جای کد که نیازمند استفاده‌ی از اعضای شیء وابستگی موردنظرمان باشیم، مثلا متدی را فراخوانی کنیم یا از یک پراپرتی آن استفاده کنیم، باید ابتدا از نال بودن یا نبودن آن اطمینان حاصل کنیم و سپس از آن استفاده نماییم؛ چون در غیر این صورت با خطای Null Pointer مواجه می‌شویم.

الگوی طراحی Null Object این مشکل را حل می‌کند که جای پاس دادن شیء Null Reference بجای شیء ای که واقعا به آن وابستگی وجود دارد و باید هر بار قبل استفاده‌ی از آن بررسی کنیم که آیا آن شیء ای که داریم با آن کار می‌کنیم نال است یا خیر، کلاسی خاصی را بسازیم که یک وابستگی غیر کاربردی است. به این معنا که قرار نیست هیچ کاری را انجام دهد و عملا یک non-functional Dependency است. این کلاس یا یک اینترفیس خاصی را پیاده سازی می‌کند و یا اینکه از یک کلاس انتزاعی ارث بری خواهد کرد؛ ولی هیچ عملکرد خاصی را نخواهد داشت. به این معنا که متدها و پراپرتی‌های این کلاس کاری را انجام نداده و یک مقدار پیشفرض و یا یک مقدار خاصی را برگشت خواهند داد. این روش به ساده سازی کد کمک خواهد کرد، چون می‌توان بدون انجام پیش شرط‌هایی مانند بررسی نال بودن یا نبودن یک شیء وابسته، از آن استفاده کرد.

این الگوی طراحی معمولا همراه با دیگر الگوهای طراحی مورد استفاده قرار می‌گیرد. بهینه‌تر است که خود کلاس Null Object به صورت Singleton پیاده سازی شود. مزیت این کار در این است که چون شیء ساخته شده از این کلاس، نه کار خاصی را انجام می‌دهد و نه حالت خاصی را نگه می‌دارد، پس ساختن شیءای از آن عملا ضرورتی نداشته و هیچگونه ارزشی ندارد و فقط سرباری را بر روی نرم افزار قرار می‌دهد. پس سزاوار است فقط به یک شیء از این کلاس اکتفا کرد و هر بار همان شیء را برگشت داد. الگوی دیگری که غالبا از الگوی Null Object در آن استفاده می‌شود، الگوی Strategy است. زمانیکه یکی از استراتژی‌ها این باشد که کار خاصی را انجام نداد و یا استراتژی مورد نظر عملکردی نداشته باشد، از الگوی Null Object استفاده می‌کنیم. الگوی دیگری که از الگوی Null Object زیاد استفاده می‌کند، الگوی Factory است. برای مثال هنگامیکه بخواهیم بر طبق شرایط برنامه یک شیء Null Reference را بسازیم و برگردانیم، از الگوی Null Object استفاده خواهیم کرد.

فرض کنید می‌خواهیم ماژولی را توسعه دهیم که وظیفه‌ی آن گزارش دادن وضعیت وقوع رخدادها است و می‌خواهیم پیام‌های وضعیت، به روش‌های مختلفی مانند ارسال ایمیل و یا ثبت لاگ در سرورهای راه دور که برای لاگ گیری تعبیه شده‌اند، انجام گیرد و در بعضی از مواقع هم می‌خواهیم برای برخی از رخداد‌ها نیاز به گزارش نباشد. در این مواقع برای استراتژی سوم از الگوی طراحی Null Object استفاده می‌کنند.


پیاده سازی الگوی طراحی Null Object

کلاس دیاگرام زیر چگونگی پیاده سازی این الگو را نشان می‌دهد. در ادامه قصد داریم بخش‌های مختلف این دیاگرام را توضیح دهیم.

Client : این کلاس دارای یک وابستگی به یک کلاس دیگر است که در بعضی مواقع نیازی به این وابستگی پیدا نمی‌کند و در صورتیکه به کارکرد اصلی وابستگی نیاز پیدا نکند، متدهای داخل کلاس Null Object را اجرا می‌کند.

DependencyBase : این قسمت کلاس پایه‌ای است که به صورت Abstract بوده و شامل همه وابستگی‌هایی است که ممکن است Client به آن وابسته باشد. همچنین این بخش، کلاس پایه‌ی کلاس Null Object هم است. شایان ذکر است که بجای استفاده از کلاس Abstract می‌توان از یک Interface هم استفاده کرد؛ چون این کلاس هیچ عملکرد مشترکی را برای زیر کلاس‌هایش پیاده سازی نمی‌کند.

Dependency : این کلاس یک عملکرد واقعی از یک وابستگی است که Client به آن وابسته است.

NullObject : این همان کلاس Null Object است که به عنوان یک وابستگی توسط Client مورد استفاده قرار می‌گیرد. این کلاس هیچ عملکرد مشخصی را ندارد ولی باید تمام اعضای کلاس پایه، یعنی DependencyBase را پیاده سازی کند.

مثال زیر کدهای اصلی پیاده سازی الگوی طراحی Null Object را نشان خواهد داد که با زبان سی شارپ نوشته شده‌است. کلاس Client، وابستگی‌های خود را از طریق سازنده دریافت خواهد کرد که به آن Constructor injection گفته می‌شود. همانطور که می‌بینید در کلاس NullObject، تنها متد Operation بازنویسی شده است و داخل آن هیچ عملکرد خاصی پیاده سازی نشده است؛ زیر تنها به وجود آن نیاز است و نه عملکرد داخلی آن.

public class Client
{
    DependencyBase _dependency;
 
    public void Client(DependencyBase dependency)
    {
        _dependency = dependency;
    }
 
    public void DoSomething()
    {
        _dependency.Operation();
    }
}
 
 
public abstract class DependencyBase
{
    public abstract void Operation();
}
 
 
public class Dependency : DependencyBase
{
    public override void Operation()
    {
        Console.WriteLine("Dependency.Operation() executed");
    }
}
 
 
public class NullObject : DependencyBase
{
    public override void Operation() { }
}


یک نمونه واقعی از الگوی طراحی Null Object

در این بخش قصد داریم مثالی از الگوی استراتژی را ارائه دهیم که در یکی از استراتژی‌هایش از کلاس Null Object استفاده خواهد کرد. در این مثال کلاسی وجود دارد به نام StatusMonitor که پس از انجام کارهایی، وضعیت انجام آن را اعلام می‌کند. ۳ نوع استراتژی برای اعلام وضعیت انجام کارها متصور است که بسته به موقعیت‌های مختلف، یکی از آنها انتخاب خواهد شد. استراتژی‌های اعلام وضعیت شامل ارسال ایمیل، ارسال وضعیت به یک وب سرویس و یا اصلا اعلام نکردن وضعیت هستند. زمانیکه قصد داریم هیچگونه وضعیتی اعلام نشود، از نمونه‌ای از کلاس Null Object استفاده خواهد شد که در این مثال کلاس NullStatusReporter این وابستگی را تامین می‌کند. همه کلاس‌های استراتژی که بیان شد تنها شامل یک متد هستند که از آن برای گزارش پیام وضعیت استفاده خواهیم کرد.

کلاس‌های EmailStatusReporter و WebServiceStstusReporter در صورتیکه بتوانند به درستی پیام‌ها را گزارش دهند، مقدار true را برگشت خواهند داد و در غیر اینصورت مقدار false برگشت داده می‌شود. اما کلاس Null Object هیچ کاری را انجام نمی‌دهد و چیزی را گزارش نمی‌دهد و تنها مقدار true را برگشت خواهد داد. اینکه این کلاس چه مقداری را برگشت دهد، قراردادی است که بین Client و Dependency انجام می‌گیرد. به این نکته هم توجه بفرمایید که کلاس NullStatusReporter به صورت Singleton پیاده سازی شده است.

public class StatusMonitor
{
    StatusReporterBase _reporter;
 
    public StatusMonitor(StatusReporterBase reporter)
    {
        _reporter = reporter;
    }
 
    public void CheckStatus()
    {
        // Do something to check status
        if (!_reporter.Report("Everything's OK"))
        {
            Console.WriteLine("Failed to report status.");
        }
    }
}
 
 
public abstract class StatusReporterBase
{
    public abstract bool Report(string message);
}
 
 
public class EmailStatusReporter : StatusReporterBase
{
    public override bool Report(string message)
    {
        try
        {
            Console.WriteLine("Emailed '{0}'.", message);
            return true;
        }
        catch
        {
            return true;
            throw;
        }
    }
}
 
 
public class WebServiceStatusReporter : StatusReporterBase
{
    public override bool Report(string message)
    {
        try
        {
            Console.WriteLine("Sent '{0}' to web service.", message);
            return true;
        }
        catch
        {
            return true;
            throw;
        }
    }
}
 
 
public class NullStatusReporter : StatusReporterBase
{
    private static NullStatusReporter _instance;
    private static object _lock = new object();
 
    private NullStatusReporter() { }
 
    public static NullStatusReporter GetReporter()
    {
        lock (_lock)
        {
            if (_instance == null) _instance = new NullStatusReporter();
        }
 
        return _instance;
    }
 
    public override bool Report(string message)
    {
        return true;
    }
}


تست کلاس Null Object

برای تست کلاس StatusMonitor باید یکی از انواع استرتژی‌ها را برایش تعیین و آن را به سازنده کلاس تزریق کرد و با آن استراتژی، کلاس را تست نمود. در کد زیر از استراتژی NullObject استفاده شده‌است. پس یک نمونه‌ی آن ساخته شده و از طریق سازنده به کلاس StatusMonitor فرستاده می‌شود. سپس متد CheckStatus فراخوانی می‌گردد. اما این متد کاری را انجام نمی‌دهد و تنها مقدار true  برگشت داده می‌شود. بررسی روش‌های دیگر را به خودتان واگذار می‌کنم.

StatusReporterBase reporter = NullStatusReporter.GetReporter();
StatusMonitor monitor = new StatusMonitor(reporter);
monitor.CheckStatus();


نظرات مطالب
کاربردهای Static reflection - قسمت اول
- یک بررسی علمی (بدون علامت تعجب احساسی در انتهای جمله) اینجا هست: (+)
در «یک میلیون بار» اجرا، حدودا 10 ثانیه تفاوت اجرا است نسبت به حالت بکارگیری رشته‌ها.
البته شما در عمل، نه در محیط آزمایشگاهی، پیدا کنید برنامه‌ای را که یک میلیون بار بخواهد خواصی را مرتبا به روز کند.
- زمانیکه LINQ هم ارائه شد، اولین مقالاتی که در این مورد ... در مورد نقد آن منتشر شد، تمرکز را گذاشتند روی کارآیی؛ که این کمی کند است! البته الان کمتر کسی است که در پروژه‌هایش حداقل از LINQ to Objects استفاده نکند. به این دلایل:
- هدف استفاده از LINQ اصلا مسابقه‌ی سرعت نیست.
- هدف تولید کدهای Strongly typed که این اهمیت‌ها را دارند: تحت نظر کامپایلر هستند، قابلیت refactoring دارند و intellisense خودکاری را به همراه خواهند داشت. تمام این‌ها نگهداری یک پروژه را (که اصل زمان اختصاص داده شده به توسعه یک نرم افزار هم همین قسمت نگهداری است)، ساده‌تر و قابل تحمل‌تر می‌کند.
- کاهش حجم کدهای نوشته شده. شما می‌تونید حجم بالایی از if-else و for و حلقه‌ها و غیره رو با یک سطر LINQ نمایش بدید. این هم در بالابردن خوانایی و همچنین نگهداری ساده‌تر برنامه مؤثر است.
- تبدیل ساده‌تر اطلاعات خام به اشیاء (LINQ to xyz ها)
و ...

شما خیلی از مزایا رو بدست خواهید آورد اما خوب مسلما این‌ها هزینه هم دارند. اما نه آنچنان که کسی بخواهد از آن‌ها صرفنظر کند.
مطالب
معرفی پروژه Orchard
معرفی پروژه Orchard:
 سیستم مدیریت محتوای Orchard توسط مایکروسافت در ژانویه سال 2011 همراه با ASP.NET MVC 3, IIS Express, SQL CE 4 ,فریم ورک Web Farm و WebMatrix ارائه شد. هدف تمامی این پروژه‌ها ایجاد قابلیتی برای توسعه آسان برنامه‌های تحت وب در محیط ویندوز بود. همانطور که PHP دارای ابزارهای مناسبی برای این منظور است. با ارائه این ابزارها مایکروسافت درخواست برنامه نویسان را برای ساده سازی تجربه توسعه وب اجابت کرد. پروژه Orchard متعلق به Outercurve Foundation (به ندرت CodePlex Foundation نیز شناخته می‌شود) است که توسط مایکروسافت پشتیبانی می‌شود. Outercurve Foundation یک سازمان غیر انتفاعی است که هدف آن تشویق و حمایت از پروژه‌های متنی بازی نظیر Orchad و یا toolkit معروف ASP.NET MVC یعنی MVC Contrib است. مایکروسافت به صورت رسمی از Orchad پشتیبانی نمی‌کند اما در حال حاضر برنامه نویسانی را جهت توسعه این سیستم استخدام کرده است.

برای پروژه Orchad سه هدف تعیین شده است :
1)فراهم نمودن و به اشتراک گذاری یک مجموعه کامپوننت جهت استفاده در برنامه‌های ASP.NET
2)ساخت تعدادی برنامه‌ی مرجع با استفاده از کامپوننت‌های فوق
3)ساخت انجمن هایی برای پشتیبانی از این کامپوننت‌ها و یا برنامه‌های مرجع

 در حال حاضر Orchard بیشتر به عنوان یک سکو (platform) برای ساخت وب سایت‌های ایجاد محتوی استفاده می‌شود آنچه در Orchard حائز اهمیت است ذکر این نکته است که این سیستم به طور کامل با استفاده از ابزار‌های متن باز نوشته شده است. Orchard از ASP.NET MVC 3.0 به همراه View engine جدید و فوق العاده آن یعنی Razor بهره می‌برد. همچنین این پروژه وابستگی زیادی به دیگر ابزارهای متن باز نظیر NHibernate برای دسترسی به داده‌ها و همچنین Autofac برای dependency injection دارد شایان ذکر است که مجوز استفاده از Orchard تحت لیسانس BSD است.

طبق اعلام وب سایت رسمی این پروژه در عرض حدود یک سالی که از ارائه این CMS می‌گذرد بیش از یک میلیون بار دانلود  و بیش از 300 ماژول و تم برای آن ساخته شده است که در گالری آن در دسترس می‌باشد. Orchard به صورت ریلیز‌های جزئی ارائه می‌شود و جدیدترن نسخه آن در هنگام نوشتن این متن 1.5.1 می‌باشد.

اما چرا به یک CMS دات نتی دیگر نیاز است ؟

تعداد زیادی سیستم‌های مدیریت محتوای تجاری و یا متن باز در طول این سال‌ها با استفاده از دات نت ارائه شده اند. (DotNetNuke (DNN بدون تردید یک از معروفترین و قدرتمندترین آن‌ها است. این CMS در ابتدا با VB.NET نوشته شد و این رویه تا مدت‌ها ادامه داشت تا اینکه در نسخه اخیر به #C تغییر کرد. اگرچه DNN و همچنین پروژه متن باز دیگری به نام Umbraco هر دو محبوب هستند اما با استفاده از WebForm‌ها پیاده سازی شده اند( البته Umbraco در نسخه 5 قصد داشت که از ASP.NET MVC استفاده کند اما علی رغم در دسترس قرار گرفتن این نسخه ظاهرا تیم Umbraco برای تمرکز بیشتر روی نسخه وب فرمی, تصمیم ندارند این پروژه را ادامه دهند.) امروزه وب فرم‌ها همانند گذشته محبوب نیستند به همین دلیل رغبت کمتری برای استفاده از این CMS‌ها  نسبت به قبل وجود دارد. با توجه به شواهد موجود بسیاری از برنامه نویسان دات نتی به سمت ASP.NET MVC مهاجرت کرده اند به همین دلیل سیستم Orchard بر مبنای این تکنولوژی نسبتا جدید دات نت پیاده شده است. با استفاده از Orchard می‌توان یک وب سایت با عملکرد بسیار بالا بدون نوشتن حتی یک خط کد ایجاد نمود. اما مانند هر سیستم مدیریت محتوی دیگری اگر بخواهیم به آن قابلیت هایی را اضافه کنیم که به صورت پیش فرض در آن نیست باید با ساختار آن به خوبی آشنا شویم و همچنین بر ابزارهای مورد نیاز این کار نیز احاطه داشته باشیم. برای دریافت اطلاعات بیشتر می‌توانید به وب سایت رسمی این پروژه در اینجا مراجعه کنید
نظرات مطالب
جایگزینی اسکریپت‌های WebResource.axd با فایل‌های استاتیک در ASP.NET Web forms
ما برای خودمون یک سیستم ساده نوشته ایم که نه تنها این کار رو می‌کنه بلکه خیلی حرفه ای‌تر و ساده‌تر این کار رو می‌کنه، مثلا حتی باهاش میشهه تمام فایل‌های یک فریم ورک مثل jQuery یا Bootstrap رو توی اسمبلی گذاشت و بعد به سادگی بهشون ارجاع داد
روش کار مون اینطوریه که توی اسمبلی که می‌خواهیم فایلهاش روی وب قابل دسترس باشند، یک attribute تعریف می‌کنیم، توی این تعریف، پسوند فایل‌های مجاز، پیشوند نشانی شون و بعضی چیزای دیگه رو تعیین می‌کنیم
در مرحله بعدی، توی فایل web.config یک هندلر اضافه می‌کنیم و نهایتا فایلی رو که می‌خواهیم آدرس بدیم، با استفاده از یک تابع خاص آدرس می‌دیم، نهایتا نشانی به صورت زیر تولید میشه:
/Dynamic/Farayan.Web.JQuery/jquery-1.5.js
اگر مایل باشین، می‌تونم فایل هاش رو براتون توی همین سایت بذارم، از دات نت هم بهتره!