مطالب
OutputCache در ASP.NET MVC
مقدمه

OutputCaching باعث می‌شود خروجیِ یک اکشن متد در حافظه نگهداری شود. با اعمال این نوع کشینگ، ASP.NET در خواست‌های بعدی به این اکشن را تنها با بازگرداندن همان مقدار قبلی ِ نگهداری شده در کش، پاسخ می‌دهد. در حقیقت با OutputCaching از تکرار چند باره کد درون یک اکشن در فراخوانی‌های مختلف جلوگیری کرده‌ایم. کش کردن باعث می‌شود که کارایی و سرعت سایت افزایش یابد؛ اما باید دقت کنیم که چه موقع و چرا از کَش کردن استفاده میکنیم و چه موقع باید از این کار امتناع کرد. 


فواید کَش کردن

- انجام عملیات هزینه دار فقط یکبار صورت میگیرد. (هزینه از لحاظ فشار روی حافظه سرور و کاهش سرعت بالا آمدن سایت)

- بار روی سرور در زمان‌های پیک کاهش می‌یابد.

- سرعت بالا آمدن سایت بیشتر میشود. 


چه زمانی باید کَش کرد؟ 

- وقتی محتوای نمایشی برای همه کاربران یکسان است.

- وقتی محتوای نمایشی برای نمایش داده شدن، فشار زیادی روی سرور تحمیل میکند.

- وقتی محتوای نمایشی به شکل مکرر در طول روز باید نمایش داده شود.

- وقتی محتوای نمایشی به طور مکرر آپدیت نمی‌شود. (در مورد تعریف کیفیت "مکرر"، برنامه نویس بهترین تصمیم گیرنده است) 


طرح مساله 

فرض کنید صفحه اول سایت شما دارای بخش‌های زیر است :

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

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

یکی از راه‌های انجام یک کش موفق و دانستن لزوم کش کردن، این است که دقیقا بدانیم ترافیک سایت روی چه صفحه ای بیشتر است. در واقع باید بدانیم در کدام صفحه "هزینه‌ی اجرای عملیات موجود در کد" بیشترین است.

فشار ترافیکی(ریکوئست‌های زیاد) و آپدیت‌های روزانه‌ی دیتابیس را، در دو کفه ترازو قرار دهید؛ چه کار باید کرد؟ این تصمیمی است که شما باید بگیرید. نگرانی خود را در زمینه آپدیت‌های روزانه و ساعتی کمتر کنید؛ در ادامه راهی را معرفی میکنیم که آپدیت‌های هر از گاهِ شما، در پاسخِ ریکوئست‌ها دیده شوند. کمی کفه‌ی کش کردن را سنگین کنید.

به هر حال، فعال کردن قابلیت کش کردن برای یک اکشن، بسیار ساده است، کافیست ویژگی ( attribute ) آن را بالای اکشن بنویسید :

[OutputCache(Duration = "60", Location = OutputCacheLocation.Server)]
        public ActionResult Index()
        {
            //کوئری یا کوئری‌های لازم برای استفاده در صفحه اصلی و تبدیل آن به یک ویو مدل جامع
        }
[OutputCache(CacheProfile = "FirstPageIndex",Location=OutputCacheLocation.Server)]
        public ActionResult Index()
        {
            //کوئری یا کوئری‌های لازم برای استفاده در صفحه اصلی و تبدیل آن به یک ویو مدل جامع
        }

دو روش فوق برای کش کردن خروجی Index  از لحاظ عملکرد یکسان است، به شرطی که در حالت دوم در وب کانفیگ و در بخش system.web آن ، یک پروفایل ایجاد کنیم کنیم :

    <caching>
      <outputCacheSettings>
        <outputCacheProfiles>
          <add name="FirstPageIndex" duration="60"/>
        </outputCacheProfiles>
      </outputCacheSettings>
    </caching>

در حالت دوم ما یک پروفایل برای کشینگ ساخته ایم و در ویژگی بالای اکشن متد، آن پروفایل را صدا زده ایم. از لحاظ منطقی در حالت دوم، چون امکان استفاده مکرر از یک پروفایل در جاهای مختلف فراهم شده، روش بهتری است. محل ذخیره کش نیز در هر دو حالت سرور تعریف شده است.

برای تست عملیات کشینگ، کافیست یک BreakPoint  درون Index قرار دهید و برنامه را اجرا کنید. پس از اجرا، برنامه روی Break Point می‌ایستد و اگر F5 را بزنیم، سایت بالا می‌آید. بار دیگر صفحه را رفرش کنیم، اگر این "بار دیگر" در کمتر از 60 ثانیه پس از رفرش قبلی اتفاق افتاده باشد برنامه روی Break Point متوقف نخواهد شد، چون خروجی اکشن، در کش بر روی سرور ذخیره شده است و این یعنی ما فشار کمتری به سرور تحمیل کرده ایم، صفحه با سرعت بالاتری در دسترس خواهد بود.

ما از تکرار اجرای کد جلوگیری کرده ایم و عدم اجرای کد بهترین نوع بهینه سازی برای یک سایت است. [اسکات الن، پلورال سایت]


چطور زمان مناسب برای کش کردن یک اکشن را انتخاب کنیم؟

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

- کشینگ با زمان طولانی؛ ما در حقیقت با اینکار منابع سرور را حفاظت میکنیم، چون عملیاتِ هزینه دار(مثل کوئری‌های حجیم) تنها یکبار در طول زمان کشینگ اجرا خواهند شد. مثلا اگر تنظیم زمان روی عدد 86400 تنظیم شود(یک روز کامل)، پس از اولین ریکوئست به اکشن مورد نظر، تا 24 ساعت بعد، این اکشن اجرا نخواهد شد و فقط خروجی آن نمایش داده خواهد شد. آیا دلیلی دارد که یک کوئری هزینه دار را که قرار نیست خروجی اش در طول روز تغییر کند به ازای هر ریکوئست یک بار اجرا کنیم؟   

اگر اطلاعات موجود در دیتابیس را تغییر دهیم چه کار کنیم که کشینگ رفرش شود؟ 

فرض کنید در همان مثال ابتدای این مقاله، شما یک پست به دیتابیس اضافه کرده اید، اما چون مثلا duration مربوط به کشینگ را روی 86400 تعریف کرده اید تا 24 ساعت از زمان ریکوئست اولیه نگذرد، سایت آپدیت نخواهد شد و محتوا همان چیزهای قبلی باقی خواهند ماند. اما چاره چیست؟

کافیست در بخش ادمین، وقتی که یک پست ایجاد میکنید یا پستی را ویرایش میکند در اکشن‌های مرتبط با Create یا Edit یا Delete چنین کدی را پس از فرمان ذخیره تغییرات در دیتابیس، بنویسید: 

Response.RemoveOutputCacheItem(Url.Action("index", "home"));

واضح است که ما داریم کشینگ مرتبط با یک اکشن متد مشخص را پاک میکنیم. با اینکار در اولین ریکوئست پس از تغییرات اعمال شده در دیتابیس، ASP.NET MVC چون میبیند کَشی برای این اکشن وجود ندارد، متد را اجرا میکند و کوئری‌های درونش را خواهد دید و اولین ریکوئست پیش از کَش شدن را انجام خواهد داد. با اینکار کشینگ ریست شده است و پس از این ریکوئست و استخراج اطلاعات جدید، زمان کشینگ صفر شده و آغاز میشود.

میتوانید یک دکمه در بخش ادمین سایت طراحی کنید که هر موقع دلتان خواست کلیه کش‌ها را به روش فوق پاک کنید! تا اپلیکیشن منتظر ریکوئست‌های جدید بماند و کش‌ها دوباره ایجاد شوند. 


جمع بندی

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

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

<caching>
      <outputCacheSettings>
        <outputCacheProfiles>
          <add name="Long" duration="86400"/>
          <add name="Average" duration="43600"/>
          <add name="Short" duration="600"/>
        </outputCacheProfiles>
      </outputCacheSettings>
    </caching>

برای مطالعه جزئیات بیشتر در مورد OutputCaching مقالات زیر منابع مناسبی هستند.

[اینجا ] و [اینجا ]

مطالب
آموزش MEF#1
Managed Extensibility Framework یا MEF کامپوننتی از Framework 4 است که برای ایجاد برنامه‌های توسعه پذیر (Extensible) با حجم کم کد استفاده میشه.این تکنولوژی به برنامه نویسان این امکان رو میده که توسعه‌های (Extension) برنامه رو بدون پیکربندی استفاده کنند. همچنین به توسعه دهندگان این اجازه رو می‌ده که به آسانی کدها رو کپسوله کنند .
MEF به عنوان بخشی از 4 NET. و Silverlight 4 معرفی شد. MEF یک راه حل ساده برای مشکل توسعه در حال اجرای برنامه‌ها ارائه می‌کند.تا قبل از این تکنولوژی ، هر برنامه‌ای که می‌خواست یک مدل Plugin را پشتیبانی کنه لازم بود که خودش زیر ساخت‌ها را از ابتدا ایجاد کنه . این Plugin‌ها اغلب برای برنامه‌های خاصی بودند و نمی‌توانستند در پیاده سازی‌های چندگانه دوباره استفاده شوند. ولی MEF در راستای حل این مشکلات ، روش استانداردی رو برای میزبانی برنامه‌های کاربردی پیاده کرده است. 
برای فهم بهتر مفاهیم یک مثال ساده رو با MEF پیاده سازی می‌کنم.
ابتدا یک پروژه از نوع Console Application ایجاد کنید . بعد با استفاده از Add Reference یک ارجاع به System.ComponentModel.Composition بدید. سپس یک Interface به نام IViewModel را به صورت زیر ایجاد کنید:
public interface IViewModel
    {
        string Name { get; set; }
    }

یک خاصیت به نام Name برای دسترسی به نام ViewModel ایجاد می‌کنیم.
سپس 2 تا ViewModel دیگه ایجاد می‌کنیم که IViewModel را پیاده سازی کنند. به صورت زیر:
ViewModelFirst:
[Export( typeof( IViewModel ) )]
    public class ViewModelFirst : IViewModel
    {
        public ViewModelFirst()
        {
            this.Name = "ViewModelFirst";
        }

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        private string _name;
    }


ViewModelSecond:
[Export( typeof( IViewModel ) )]
    public class ViewModelSecond : IViewModel
    {
        public ViewModelSecond()
        {
            this.Name = "ViewModelSecond";
        }

        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        private string _name;
    }


Export Attribute استفاده شده در بالای کلاس‌های ViewModel به این معنی است که این کلاس‌ها اینترفیس IViewModel رو Export کردند تا در جای مناسب بتونیم این ViewModel ‌ها Import کنیم.(Import , Export از مفاهیم اصلی در MEF هستند)
حالا نوبت به پیاده سازی کلاس Plugin می‌رسه.
public class PluginManager
    {
        public PluginManager()
        {

        }

        public IList<IViewModel> ViewModels
        {
            get
            {
                return _viewModels;
            }
            private set
            {
                _viewModels = value;
            }
        }

        [ImportMany( typeof( IViewModel ) )]
        private IList<IViewModel> _viewModels = new List<IViewModel>();

        public void SetupManager()
        {
            AggregateCatalog aggregateCatalog = new AggregateCatalog();

            CompositionContainer container = new CompositionContainer( aggregateCatalog );

            CompositionBatch batch = new CompositionBatch();

            batch.AddPart( this );

            aggregateCatalog.Catalogs.Add( new AssemblyCatalog( Assembly.GetExecutingAssembly() ) );           

            container.Compose( batch );
        }

کلاس PluginManager برای شناسایی و استفاده از کلاس هایی که صفت‌های Export رو دارند نوشته شده(دقیقا شبیه یک UnityContainer در Microsoft Unity Application Block یا IKernel در Ninject) عمل می‌کنه با این تفاوت که نیازی به Register با Bind کردن ندارند)
ابتدا بک لیست از کلاس هایی که IViewModel رو Export کردند داریم.
بعد در متد SetupManager ابتدا یک AggregateCatalog نیاز داریم تا بتونیم Composition Part‌ها رو بهش اضافه کنیم. به کد زیر توجه کنید:
 aggregateCatalog.Catalogs.Add( new AssemblyCatalog( Assembly.GetExecutingAssembly() ) );

تو این قطعه کد من یک Assembly Catalog رو که به Assembly جاری برنامه اشاره می‌کنه به AggregateCatalog اضافه کردم.
متد (batch.AddPart(this در واقع به این معنی است که به MEF گفته می‌شود این کلاس ممکن است شامل Export هایی باشد که به یک یا چند Import وابستگی دارند.
متد (AddExport(this در CompositionBatch به این معنی است که این کلاس ممکن است شامل Exportهایی باشد که به Import وابستگی ندارند.
حالا برای مشاهده نتایج کد زیر را در کلاس Program اضافه می‌کنیم:
static void Main( string[] args )
        {
            PluginManager plugin = new PluginManager();

            Console.WriteLine( string.Format( "Number Of ViewModels Before Plugin Setup Is [ {0} ]", plugin.ViewModels.Count ) );

            Console.WriteLine( Environment.NewLine );

            plugin.SetupManager();

            Console.WriteLine( string.Format( "Number Of ViewModels After Plugin Setup Is [ {0} ]", plugin.ViewModels.Count ) );

            Console.ReadLine();
        }

در کلاس بالا ابتدا تعداد کلاس‌های موجود در لیست ViewModels رو قبل از Setup کردن Plugin نمایش داده سپس بعد از Setup  کردن Plugin  دوباره تعداد کلاس‌های موجود در لیست ViewModel رو مشاهده می‌کنیم.که خروجی به شکل زیر تولید خواهد شد.


متد SetupManager در کلاس Plugin (با توجه به AggregateCatalog) که در این برنامه فقط Assembly  جاری رو بهش اضافه کردیم تمام کلاس هایی رو که نوع IViewModel رو Export کردند پیدا کرده و در لیست اضافه می‌کنه(این کار رو با توجه به ImportMany Attribute) انجام میده. در پست‌های بعدی روش استفاده از MEF رو در Prism یا WAF توضیح می‌دم.
مطالب
نکاتی در مورد نوشتن یک مطلب خوب و گیرا در یک سایت
تفاوتی نمی‌کند در چه رشته‌ای یا حرفه‌ای مشغول به کار هستید؛ تفاوتی نمی‌کند در چه زمینه‌ای قصد دارید مطلبی را منتشر کنید. برای تهیه یک مطلب خوب و ماندگار، باید یک سری اصول کلی را در نوشتن  رعایت کرد که در ادامه به مرور آن‌ها خواهیم پرداخت.

1) مطلب شما نیاز به مقدمه دارد
نیاز به مقدمه داشتن به معنای نوشتن کلمه «مقدمه» در ابتدای یک متن نیست. به این معنا است که به خواننده بگوئید مشکل کجا بوده یا به چه دلیلی قصد دارید مطلب جاری را منتشر کنید. بنابراین جهت تهیه یک مطلب خوب، یک راست اصل مطلب را شروع نکنید. لازم است چند سطری در مورد علت انتشار آن توضیح دهید.

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

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

4) تکرار کلمات و جملات یکسان را در متن خود به حداقل برسانید
برای مثال مدام در متن خود جمله «همانطور که ملاحظه می‌کنید» را تکرار نکنید. استفاده از افعال تکراری و جملات تکراری در یک متن باید حداقل باشند. برای نمونه اگر جمله جاری به «می‌شود» ختم خواهد شد، جمله بعدی را به «می‌گردد» ختم کنید. اگر جمله‌ای دارای کلمات «برای مثال» است، جمله بعدی بهتر است به همراه کلمات «برای نمونه» باشد.

5) از جملات طولانی استفاده نکنید
یک جمله باید حداکثر یک سطر یا یک سطر و نصفی طول داشته باشد و گرنه خواننده را به شدت در دنبال کردن آن به زحمت خواهید انداخت. جملات طولانی را به جملاتی کوتاه‌تر خرد کنید.

6) استفاده از علامت تعجب را به حداقل برسانید
اشخاصی که مدام از چندین علامت تعجب پشت سرهم استفاده می‌کنند یا مدام از علامت سؤال به همراه چندین علامت تعجب بهره می‌گیرند، حس مسخره کردن شخص مقابل و همچنین عدم تعادل روانی خود را القاء می‌کنند.

7) در متن خود از تصاویر استفاده کنید
انسان موجودی است بصری. قدرت یادگیری ما از طریق دیدن چند برابر زمانی است که از طریق شنیدن یا خواندن نسبت به فراگیری مطلبی اقدام می‌کنیم.
« ما ...
10 درصد چیزهایی را که می‌خوانیم
20 درصد چیزهایی را که می‌شنویم
30 درصد چیزهایی را که می‌بینیم
50 درصد چیزهایی را که می‌بینیم و می‌شنویم
70 درصد چیزهایی را که در موردشان بحث می‌کنیم
80 درصد چیزهایی را که تجربه می‌کنیم
95 درصد چیزهایی را که به دیگران می‌آموزیم
... یاد می‌گیریم
»

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

9) به صفحات داخلی سایت خود لینک دهید
در مطلب تهیه  شده سعی کنید به مطالب مشابه داخلی سایت خود لینک دهید. احتمال کپی شدن مطالب شما بسیار زیاد است. به این ترتیب می‌توانید خواننده‌ها را در لابلای متن خود به مرجع اصلی هدایت کنید.

10) دست به اختراع برچسب‌های جدید، پراکنده و بیهوده نزنید
اگر گروه بندی مطالب یک سایت بر اساس برچسب‌ها است و تاکنون برچسب‌های متعددی تعریف شده است، بهتر است از همان‌ها استفاده کنید تا اینکه دست به اختراع زده و یک برچسب کاملا جدید را ثبت کنید. برای مثال اگر مطلب شما در مورد Entity framework است و تا کنون 20 مطلب ذیل این گروه ثبت شده، اختراع برچسب جدید EF Code first نه تنها کمکی نخواهد کرد، بلکه خواننده‌ای را که به دنبال یافتن مطالب یک گروه خاص است، سر در گم می‌کند. یا اگر قصد دارید یک برچسب کاملا جدید را اضافه کنید، حتما از یک برچسب کلی موجود نیز استفاده کنید تا روابط بین مطالب حفظ شوند.

11) مطالب شما بهتر است یک قسمت نتیجه گیری نیز داشته باشد
بهتر است در پایان یک مطلب، خلاصه بحث، پیشنهادها یا حتی سؤالاتی را مطرح کنید تا بتوانید خواننده را تا حدودی وادار به عکس العمل نمائید.

12) تا حد امکان از منابع سایت خود استفاده کنید
اگر قرار  است تصویری در متن قرار گیرد، اگر نیاز است فایلی در سایت مطرح شود، بهتر است این موارد در سایت جاری هاست شوند؛ تا اینکه تصویر یک سایت دیگر را مستقیما در سایت خود لینک کنیم.

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

14) تصاویر ارائه شده را فشرده کنید
فرمت مناسب ارائه تصویر در یک سایت bmp نیست. بهترین فرمت برای سایت‌ها png است؛ از لحاظ حفظ تعداد رنگ و همچنین کاهش حجم. به علاوه ابزارهای زیادی برای کاهش حجم فایل‌های png با حداقل افت کیفیت وجود دارند.

15) در مورد کدهای خود توضیح دهید
این مورد خصوصا به سایت‌های برنامه نویسی مرتبط می‌شود. اینکه چند سطر کد بدون توضیح را در یک مطلب قرار داده‌اید، نه لطفی است و نه اهمیتی دارد! هزاران هزار سطر از این دست کدها در GitHub، CodPlex و sourceforge وجود دارند. فرق کار شما با آن‌ها در چیست؟
باید یک قسمت «توضیحات» ذیل کدهای ارائه شده وجود داشته باشد. همان نکاتی را که حین تهیه کدها در ذهن داشتید باید بتوانید توضیح دهید و گرنه ... کار شما ارزشی نخواهد داشت.

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

17) یک راست به سراغ کدنویسی و اصل مطلب نروید
اگر قرار است در مورد یک فناوری جدید در طی چند جلسه بحث کنید، لازم است یک جلسه کامل در مورد «چرا به این فناوری نیاز داریم» توضیح دهید. بنابراین ذکر اینکه بدون مقدمه به سراغ کدنویسی می‌رویم، سؤالات بسیاری را به جا خواهند گذاشت مانند ... «مشکل روش‌‌های قبلی چی هست؟» «مزیت این روش جدید در کجاست؟» و تا نتوانید این مسایل را شرح دهید، کار شما خریدار نخواهد داشت.

18) در زبان فارسی نیم فاصله‌ها را رعایت کنید
در نگارش زبان فارسی فرق است بین «آمده ام» و «آمده‌ام» و یا «می شود» را باید «می‌شود» نوشت. می‌شود اندکی وقت گذاشت و با مبحث نیم فاصله آشنا شد .

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

 
اشتراک‌ها
هرکسی از یک جایی آغاز می کند

دیدار مدیر اجرایی شرکت مایکروسافت از دانش آموزان مدرسه امور مالی و فناوری در اردوی یک هفته ای "ساعات کدنویسی" که توسط سایت code.org راه اندازی شده. 

هرکسی از یک جایی آغاز می کند
نظرات مطالب
پیاده سازی JSON Web Token با ASP.NET Web API 2.x
سلام، آیا یک استانداردی برای مقادیر پیش فرض زمان منقضی شدن Access Token وRefresh Token وجود دارد؟ به عنوان مثال آیا این منطقی است که مثلا زمان منقضی شدن Access Token را یک هفته و زمان منقضی شدن Refresh Token را یک ماه در نظر بگیریم؟
نظرات مطالب
معرفی برنامه‌ی Subtitle Tools
سلام آقای وحید نصیری، منم وحید نصیری هستم لینک وبلاگ شما رو تو هفته نامه کلیک پیدا کردم.

این شباهت اسم و فامیلی برام جالب بود گفتم یه عرض ادبی بکنم

موفق باشی.
نظرات اشتراک‌ها
کتاب رایگان ساخت Mobile Websites با MVC4
من تا حد امکان از طرح مسایل وارز در این سایت پرهیز می‌کنم و از دیگران هم درخواست کردم اینکار را انجام ندهند (در طرح مقالات یا لینک‌های سایت). لینک‌های کتاب‌ها یا مجلاتی را هم که در این سایت مشاهده می‌کنید اکثرا رایگان هستند مانند همین مطلب جاری.
علت چیست؟ پرداختن بیش از حد به وارز شما را از تولید محتوا دور می‌کند و صرفا تبدیل خواهید شد به یک مصرف کننده ساده نهایی.
هنر این است که مثلا از محصولات تلریک استفاده می‌کنید؟ آیا می‌تونید در مورد نحوه طراحی API اون نصف صفحه مطلب بنویسید؟ یا اینکه نه، فقط یک مصرف کننده جزء هستید که به دنبال کرک و برنامه مفت.
آیا می‌تونید از 10 تا کتاب سی شارپی که در مورد پردازش موازی دانلود کردید 5 تا مقاله دربیارید؟
از 100 گیگ فیلم آموزشی که دانلود کردید 10 تا مطلب منتشر کنید؟
هدف کلی این سایت هم همین است. آیا می‌تونید محتوا تولید کنید؟ یا اینکه فقط کوش، فقط می‌خوام، فقط نیست. فقط زود باش.


پ.ن.
مادر تمام سایت‌های وارز مرتبط با برنامه نویسی، سایتی است با آدرس «board4allcz.eu». اگر کمی دقت کنید، تعداد ایرانی‌های فعال در آن هم بسیار زیاد است! ولی واقعا ضرورتی نداره کار یک سایت دیگر رو ما اینجا تکرار کنیم.
مطالب
چند نکته اضافه برای Refactoring
Refactoring عامل خوانایی کد و در بسیاری از مواقع، سبب بالاتر رفتن کارآیی برنامه است. در واقع حتی بسیاری از قوانین Refactoring خود یک الگوی طراحی به شمار می‌آیند. در این مقاله به تعدادی از مباحث Refactoring می‌پردازیم:

یک: به جای بازگرداندن شماره خطا، از استثناءها استفاده کنید. نمونه زیر را ببینید:
public int ReturnErrorCodes(int n1)
{
         if(n1==0)
               return -1;
          if(n1<0)
                 return -2;
            if(n1>_max)
                return -3;
            return n1;
}
همانطور که می‌بینید در کد بالا شماره‌های خطا بازگشت داده می‌شوند. در این حالت می‌توانیم آن‌ها را با استثناءها جایگزین کنیم:
public int ReturnErrorCodes(int n1)
{
         if(n1==0)
                throw new ZeroException();
          if(n1<0)
                 throw new MinException();
            if(n1>_max)
                throw new MaxException();
            return n1;
}

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

 دو. یک شیء کامل را بازگردانید.
نمونه کد زیر را ببینید:
Public Void Draw()
{
        var x=_pointDetector.X;
        var y=_pointerDetector.Y;
        _rectangle.Draw(x,y);
}
در این شیوه، هر چقدر متغیرهای برگشتی افزایش پیدا کنند، اهمیت استفاده از آن بیشتر می‌شود. برای حل این مسئله باید به جای برگرداندن تک تک مقادیر، همه آن‌ها را در قالب یک شیء برگردانید:
public Void Draw()
{
     var point = _pointDetector.Point;
     _rectangle.Draw(point);
}
از مزایای استفاده‌ی از الگو، این است که تعداد خطوط شما در بدنه اصلی، کاهش می‌یابد و اگر در آینده نیاز به افزایش تعداد خروجی‌ها باشد، لازم نیست که بدنه‌ی اصلی را هم تغییر بدهید و مرتب کدی یا خطی را به آن اضافه کنید.

سه
. شروط یکسان را تابع نویسی کنید. گاهی از اوقات مانند کد زیر پیش می‌آید که خروجی چندین شرط شما، خروجی یکسانی دارند. جهت این کار می‌توانید تمام این شرط‌ها را به یک تابع یا متد دیگر منتقل کنید:
public void Conditions(){
     if(a==0)
             return 0;
     if(b==0)
             return 0;
     if(c==0)
             return 0;
     if(d==0)
             return 0;
}
به جای آن می‌نویسیم:
public void Conditions()
{
          if(allConditions())
               return 0;
}
بدین صورت بدنه اصلی خلاصه‌تر شده و شرط‌ها به متدی با نامی که هدف آن را مشخص می‌کند انتقال می‌یابند.

چهار. چند خط کد شرطی را در یک شرط ننویسید و آنها را به متغیرهای جداگانه انتساب دهید. نمونه زیر را ببینید:
public void renderBanner() {
  if ((platform.toUpperCase().indexOf("MAC") > -1) &&
       (browser.toUpperCase().indexOf("IE") > -1) &&
        wasInitialized() && resize > 0 )
  {
    // do something
  }
}
در این حالت بهتر است هر شرط به یک خط و یک متغیر انتقال یابد تا خطوط تمیزتر و خلاصه‌تر و قابل فهم‌تری داشته باشیم:
public void renderBanner() {
  bool isMacOs = platform.toUpperCase().indexOf("MAC") > -1;
  bool isIE = browser.toUpperCase().indexOf("IE") > -1;
  bool wasResized = resize > 0;

  if (isMacOs && isIE && wasInitialized() && wasResized) {
    // do something
  }
}

پنج
. معرفی اکستنشن محلی: گاهی اوقات از کلاس‌هایی استفاده می‌کنید که شامل متد یا خاصیتی که احتیاج دارید نیستند و دسترسی به سورس آن کلاس هم امکان پذیر نیست یا هزینه سنگینی دارد. در این صورت می‌توانید از یک زیر کلاس یا Wrapper Class استفاده کنید.
به عنوان مثال متد NextDay جایگاه آن در DateTime است. برای افزودن این خاصیت دو راه دارید که یک زیر کلاس از DateTime ایجاد کنید و متدی را به آن اضافه کنید یا اینکه کلاس DateTime را در یک کلاس دیگر بپیچانید (محصور کنید).
public class Globalization:DateTime
{
     public int NextDay()
     {
      }
}
یا
public class Globalization
{
    public DateTime DT{get;set;}
     public int NextDay()
     {
      }
}

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

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

نظرات مطالب
ارتقاء به ASP.NET Core 1.0 - قسمت 19 - بومی سازی
- در نگارش‌های جدید ASP.NET Core، بسته‌ی بومی سازی آن، خطاهای یافت نشدن کلیدها را توسط ILogger آن لاگ می‌کند (و هیچ استثنایی را مشاهده نخواهید کرد). به همین جهت لاگ کردن را در برنامه‌ی خود فعال کنید و خروجی آن‌را جهت یافتن عباراتی مانند search for بررسی کنید (دقیقا عنوان می‌کند که کجاها را برای یافتن معادل‌ها بررسی کرده‌است و چیزی یافت نشده).
- برای مثال اگر از قالب پیش‌فرض ASP.NET Core 2.1 استفاده می‌کنید، لاگ کردن در کنسول و همچنین دیباگ آن فعال است (بدون نیاز به تنظیم اضافه‌تری). در اینجا برنامه را در حالت dotnet watch run اجرا کنید (این دستور را در ریشه‌ی پروژه اجرا کنید) و سپس در کنسول جاری، عبارات لاگ شده را بررسی کنید. یا پنجره‌ی debug در ویژوال استودیو نیز همینکار را انجام می‌دهد.
بررسی لاگ‌های برنامه جزو الزامات کار با برنامه‌های NET Core. است. در اینجا کمتر استثناءها را مشاهده می‌کنید و چون یک فریم ورک توکار Logging را به همراه دارد، همه‌جا از آن برای گزارش مشکلات، در پشت صحنه استفاده می‌شود.