‏نمایش پست‌ها با برچسب Tips. نمایش همه پست‌ها
‏نمایش پست‌ها با برچسب Tips. نمایش همه پست‌ها

۱۳۹۰/۱۰/۱۸

وادار كردن خود به كامنت نوشتن


قابليت جالبي در ويژوال استوديو وجود دارد كه شايد كمتر در مورد آن مطلب نوشته شده است و آن هم تنظيم پروژه به نحوي است كه اگر براي كليه موارد public كامنتي نوشته نشود، برنامه كامپايل نخواهد شد. همچنين اگر نام پارامتري را تغيير داديد، اما كامنت مرتبط با آن را به روز نكرديد، باز هم خطاي كامپايل را دريافت خواهيد كرد كه از اين لحاظ هم بسيار عالي است و به نوعي «وادار كردن خود به كامنت نوشتن» است.

براي اين تنظيم، ابتدا به برگه خواص پروژه مراجعه كنيد. سپس در قسمت Build تنظيمات زير را اعمال نمائيد:
Treat warnings as errors را بر روي All قرار دهيد.
در ذيل آن، در قسمت Output‌، گزينه‌ي XML Documentation file را تيك بزنيد.

البته اين تغيير بهتر است در يك پروژه جديد مد نظر باشد، چون اگر الان اقدام به اين تنظيم كنيد، به طور قطع از خير آن خواهيد گذشت! كامنت نويسي به مرور و در حين توسعه يك برنامه يا كتابخانه قابل تحمل است وگرنه اگر براي روز آخر قرار داده شود، به احتمال زياد انجام نخواهد شد.

مطالب مرتبط:



۱۳۹۰/۱۰/۱۶

اهميت code review


تا جايي كه دقت كردم (در بلاگ‌هايي كه منتشر مي‌شوند) در آنسوي آب‌ها، «code review» يك شغل محسوب مي‌شود. سازمان‌ها، شركت‌ها و امثال آن از مشاورين يا برنامه نويس‌هايي با مطالعه بيشتر دعوت مي‌كنند تا از كدهاي آن‌ها اشكال‌گيري كنند و بابت اينكار هم هزينه مي‌كنند.
اگر علاقمند باشيد قسمتي از يك پروژه سورس باز دريافت شده از همين دور و اطراف را با هم مرور كنيم:

//It's only for code review purpose!
protected void Button1_Click1(object sender, EventArgs e)
{        
        string  strcon;        
        string strUserURL;
        string strSQL;
        string strSQL1;
        strSQL = "SELECT UserLevel FROM listuser " + "WHERE Username='" + TextBox2.Text + "' " + "And Password='" + TextBox3.Text + "';";
        strSQL1 = "SELECT Pnumber FROM listuser " + "WHERE Username='" + TextBox2.Text + "' " + "And Password='" + TextBox3.Text + "';";
        strcon = @"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\bimaran.mdf;Integrated Security=True;User Instance=True";
        SqlConnection myConnection = new SqlConnection(strcon);

        SqlCommand myCommand = new SqlCommand(strSQL, myConnection);
        SqlCommand myCommand1 = new SqlCommand(strSQL1, myConnection);
        myConnection.Open();

        strUserURL = (string)myCommand.ExecuteScalar();
        send = (string)myCommand1.ExecuteScalar();
        myCommand.Dispose();
        myCommand1.Dispose();
        myConnection.Close();


        if (strUserURL != null)
        {                      
            Label1.Text = "";

            url = "?Pn=" + code(send);
            FormsAuthentication.SetAuthCookie(TextBox2.Text, true);
            Response.Redirect("Page/" + strUserURL + url);
       }
        else
            Label3.Text = "چنین کاربری با این مشخصات ثبت نشده است.";
}


مروري بر اين كد يا «مشكلات اين كد»:
- كانكشن استرينگ داخل كدها تعريف شده. يعني اگر نياز به تغييري در آن بود بايد كدهاي برنامه تغيير كنند. آن هم نه فقط در اين تابع بلكه در كل برنامه.
- از پارامتر استفاده نشده. كد 100 درصد به تزريق اس كيوال آسيب پذير است.
- نحوه‌ي dispose شيء كانكشن غلط است. هيچ ضمانتي وجود ندارد كه كدهاي فوق سطر به سطر اجرا شود و خيلي زيبا به سطر بستن كانكشن استرينگ برسد. فقط كافي است اين ميان يك استثنايي صادر شود و تمام. به عبارتي اين سايت فقط با كمتر از 30 كاربر همزمان از كار مي‌افته. بعد نيايد بگيد من يك سرور دارم با 16 گيگ رم ولي باز كم مياره! همش برنامه كند ميشه. همش سايت بالا نمياد!
- همين تعريف كردن متغيرها در ابتداي تابع يعني اين برنامه نويس هنوز حال و هواي ANSI C را دارد!
- مهم نيست لايه بندي كنيد. ولي يك لايه در اين نوع پروژه‌ها الزامي است و آن هم DAL نام دارد. DAL يعني كثافت كاري نكنيد. يعني داخل هر تابع كُپه كُپه بر نداريد open و close بذاريد. بريد يك تابع يك گوشه‌اي درست كنيد كه اين عمليات را محصور كند.
- همين وجود Button1 و Label1 يعني تو خود شرح مفصل بخوان از اين مجمل!

۱۳۹۰/۰۸/۰۷

محاسبه مجدد ميزان مصرف حافظه‌ي برنامه‌هاي دات نت


اگر به ميزان مصرف حافظه‌ اوليه‌ي برنامه‌هاي دات نت دقت كنيم، نسبت به مثلا يك برنامه‌ي MFC چند برابر به نظر مي‌رسند و ... اين علت دارد:
زمانيكه يك برنامه‌ي مبتني بر دات نت اجرا مي‌شود، ابتدا JIT compiler شروع به كار كرده و شروع به كامپايل برنامه مي‌كند. اين بارگزاري هم در همان پروسه‌ي اصلي برنامه انجام مي‌شود. به همين جهت ميزان مصرف حافظه‌ي برنامه‌هاي دات نت عموما بالا به نظر مي‌رسد.
اكنون سؤال اينجا است كه آيا مي توان اين حافظه‌اي را كه ديگر مورد استفاده نيست (و توسط JIT compiler اخذ شده) به سيستم بازگرداند و محاسبه‌ي مجددي را در اين مورد انجام داد. پاسخ به اين سؤال را در متد ReEvaluateWorkingSet زير مي‌توان مشاهده كرد:


using System;
using System.Diagnostics;

namespace Toolkit
{
    public static class Memory
    {
        public static void ReEvaluateWorkingSet()
        {
            try
            {
                Process loProcess = Process.GetCurrentProcess();
                //it doesn't matter what you set maxWorkingSet to
                //setting it to any value apparently causes the working set to be re-evaluated and excess discarded
                loProcess.MaxWorkingSet = (IntPtr)((int)loProcess.MaxWorkingSet + 1);
            }
            catch
            {
                //The above code requires Admin privileges. 
                //So it's important to trap exceptions in case you're running without admin rights. 
            }
        }
    }
}

در اين متد ابتدا پروسه جاري دريافت شده و سپس MaxWorkingSet به يك عدد دلخواه تنظيم مي‌شود. مهم نيست كه اين عدد چه چيزي باشد، زيرا اين تنظيم سبب مي‌شود كه در پشت صحنه به شكل حساب شده‌اي حافظه‌اي كه مورد استفاده نيست به سيستم بازگردانده شود و سپس عددي كه در task manager نمايش داده مي‌شود، مجددا محاسبه گردد. همچنين بايد دقت داشت كه اين كد تنها با دسترسي مديريتي قابل اجرا است و به همين دليل وجود اين try/catch ضروري است.

نحوه استفاده از متد ReEvaluateWorkingSet در برنامه‌هاي WinForms :
فايل Program.cs را يافته و سپس در روال رويداد گردان Idle برنامه، متد ReEvaluateWorkingSet را فراخواني كنيد (مثلا هر زمان كه برنامه minimized شد اجرا مي‌شود):

//Program.cs
namespace MemUsage
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            //...

            Application.Idle += applicationIdle;
        }

        static void applicationIdle(object sender, EventArgs e)
        {
            Memory.ReEvaluateWorkingSet();
        }
    }
}

نحوه استفاده از متد ReEvaluateWorkingSet در برنامه‌هاي WPF :
فايل App.xaml.cs را يافته و سپس در روال رويدادگردان Deactivated برنامه، متد ReEvaluateWorkingSet را فراخواني كنيد:

//App.xaml.cs

public App()
{
    this.Deactivated += appDeactivated;
}

void appDeactivated(object sender, EventArgs e)
{
     Memory.ReEvaluateWorkingSet();
}

تاثير آن هم قابل ملاحظه است (حداقل از لحاظ رواني!). تست كنيد!

۱۳۹۰/۰۷/۰۱

بيشترين كاربرد دات نت فريم ورك تابحال در كجا بوده است؟


برخلاف تصور عموم، كاربرد اصلي دات نت فريم ورك در طي اين چندين و چند سالي كه از ارائه آن مي‌گذرد، در توسعه‌ي گسترده برنامه‌هاي دسكتاپ نبوده است. عمده كاربرد آن در تهيه برنامه‌هاي وب است. براي نمونه مي‌توان به آمارگيري زير سيستم‌هاي مورد استفاده دات نت در بين برنامه نويس‌ها در سال 2010 مراجعه كرد [^] و كاربردهاي وب آن را حداقل بايد در جمع استفاده از WebForms ، Ajax و MVC جستجو كرد (البته اگر WCF و ASMX را نديد بگيريم كه آن‌ها هم عمده كاربردشان در پروژه‌هاي وب است). اين اعداد و ارقام سال 2010 را اگر بخواهيم از بيشترين به كمترين ليست كنيم، حاصل آن به صورت زير درخواهد آمد:

01 - WebForms
02 - Ajax
03 - WCF
04 - Linq to SQL
05 - MVC
06 - WinForms
07 - ASMX
08 - Silverlight
09 - WPF
10 - ADO DataSets
11 - Entity-Framework (EF)
12 - Workflow
13 - ADO.NET Data Services
14 - DynamicData
15 - CardSpace

مورد ديگري كه شايد براي خيلي‌ها جالب توجه باشد، آمار تعداد سايت‌هايي است كه از ASP.NET استفاده مي‌كنند، در مقابل تعداد سايت‌هايي كه بر پايه PHP تهيه شده‌اند. مطابق آمار اين سايت [^] و [^] در حال حاضر در بين يك ميليون سايت برتر دنيا (سايت‌هايي كه بيشترين ترافيك وب را به خود اختصاص داده‌اند) حدود 216 هزار سايت از ASP.NET و 394 هزار سايت از PHP استفاده مي‌كنند. از مابقي وب سايت‌هاي موجود در وب، حدود 27 ميليون سايت از ASP.NET و 26 ميليون سايت از PHP استفاده مي‌كنند. اين اعداد و ارقام از اين جهت حائز اهميت هستند كه مدت زمان ارائه ASP.NET كمتر از PHP است و همچنين بيشترين كاربرد ASP.NET در سرورهاي ويندوزي است، برخلاف PHP كه علاوه بر ويندوز، در بين سرورهاي لينوكسي نيز گزينه‌ي بسيار محبوبي محسوب مي‌شود.

۱۳۹۰/۰۶/۲۸

تبديل عدد به حروف


به طور قطع توابع و كلاس‌هاي تبديل عدد به حروف، در جعبه ابزار توابع كمكي شما هم پيدا مي‌شوند. روز قبل سعي كردم جهت آزمايش، عدد 3000,000,000,000,000 ريال را با كلاسي كه دارم تست كنم و نتيجه overflow يا اصطلاحا تركيدن سيستم بود! البته اگر مطالب اين سايت را دنبال كرده باشيد پيشتر در همين راستا مطلبي در مورد نحوه‌ي صحيح بكارگيري توابع تجمعي SQL در اين سايت منتشر شده است و جزو الزامات هر سيستمي است (تفاوتي هم نمي‌كند كه به چه زباني تهيه شده باشد). اگر آ‌ن‌را رعايت نكرده‌ايد، سيستم شما «روزي» دچار overflow خواهد شد.

در كل اين كلاس تبديل عدد به حروف را به صورت ذيل اصلاح كردم و همچنين دو زبانه است؛ چيزي كه كمتر در پياده سازي‌هاي عمومي به آن توجه شده است:

using System.Collections.Generic;
using System.Linq;

namespace NumberToWordsLib
{
 /// <summary>
 /// Number to word languages
 /// </summary>
 public enum Language
 {
  /// <summary>
  /// English Language
  /// </summary>
  English,

  /// <summary>
  /// Persian Language
  /// </summary>
  Persian
 }

 /// <summary>
 /// Digit's groups
 /// </summary>
 public enum DigitGroup
 {
  /// <summary>
  /// Ones group
  /// </summary>
  Ones,

  /// <summary>
  /// Teens group
  /// </summary>
  Teens,

  /// <summary>
  /// Tens group
  /// </summary>
  Tens,

  /// <summary>
  /// Hundreds group
  /// </summary>
  Hundreds,

  /// <summary>
  /// Thousands group
  /// </summary>
  Thousands
 }

 /// <summary>
 /// Equivalent names of a group 
 /// </summary>
 public class NumberWord
 {
  /// <summary>
  /// Digit's group
  /// </summary>
  public DigitGroup Group { set; get; }

  /// <summary>
  /// Number to word language
  /// </summary>
  public Language Language { set; get; }

  /// <summary>
  /// Equivalent names
  /// </summary>
  public IList<string> Names { set; get; }
 }

 /// <summary>
 /// Convert a number into words
 /// </summary>
 public static class HumanReadableInteger
 {
  #region Fields (4)

  private static readonly IDictionary<Language, string> And = new Dictionary<Language, string>
  {
   { Language.English, " " },
   { Language.Persian, " و " } 
  };
  private static readonly IList<NumberWord> NumberWords = new List<NumberWord>
  {
   new NumberWord { Group= DigitGroup.Ones, Language= Language.English, Names=
    new List<string> { string.Empty, "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine" }},
   new NumberWord { Group= DigitGroup.Ones, Language= Language.Persian, Names=
    new List<string> { string.Empty, "يك", "دو", "سه", "چهار", "پنج", "شش", "هفت", "هشت", "نه" }},

   new NumberWord { Group= DigitGroup.Teens, Language= Language.English, Names=
    new List<string> { "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen" }},
   new NumberWord { Group= DigitGroup.Teens, Language= Language.Persian, Names=
    new List<string> { "ده", "يازده", "دوازده", "سيزده", "چهارده", "پانزده", "شانزده", "هفده", "هجده", "نوزده" }},

   new NumberWord { Group= DigitGroup.Tens, Language= Language.English, Names=
    new List<string> { "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" }},
   new NumberWord { Group= DigitGroup.Tens, Language= Language.Persian, Names=
    new List<string> { "بيست", "سي", "چهل", "پنجاه", "شصت", "هفتاد", "هشتاد", "نود" }},

   new NumberWord { Group= DigitGroup.Hundreds, Language= Language.English, Names=
    new List<string> {string.Empty, "One Hundred", "Two Hundred", "Three Hundred", "Four Hundred", 
     "Five Hundred", "Six Hundred", "Seven Hundred", "Eight Hundred", "Nine Hundred" }},
   new NumberWord { Group= DigitGroup.Hundreds, Language= Language.Persian, Names=
    new List<string> {string.Empty, "يكصد", "دويست", "سيصد", "چهارصد", "پانصد", "ششصد", "هفتصد", "هشتصد" , "نهصد" }},

   new NumberWord { Group= DigitGroup.Thousands, Language= Language.English, Names=
     new List<string> { string.Empty, " Thousand", " Million", " Billion"," Trillion", " Quadrillion", " Quintillion", " Sextillian",
   " Septillion", " Octillion", " Nonillion", " Decillion", " Undecillion", " Duodecillion", " Tredecillion",
   " Quattuordecillion", " Quindecillion", " Sexdecillion", " Septendecillion", " Octodecillion", " Novemdecillion",
   " Vigintillion", " Unvigintillion", " Duovigintillion", " 10^72", " 10^75", " 10^78", " 10^81", " 10^84", " 10^87",
   " Vigintinonillion", " 10^93", " 10^96", " Duotrigintillion", " Trestrigintillion" }},
   new NumberWord { Group= DigitGroup.Thousands, Language= Language.Persian, Names=
     new List<string> { string.Empty, " هزار", " ميليون", " ميليارد"," تريليون", " Quadrillion", " Quintillion", " Sextillian",
   " Septillion", " Octillion", " Nonillion", " Decillion", " Undecillion", " Duodecillion", " Tredecillion",
   " Quattuordecillion", " Quindecillion", " Sexdecillion", " Septendecillion", " Octodecillion", " Novemdecillion",
   " Vigintillion", " Unvigintillion", " Duovigintillion", " 10^72", " 10^75", " 10^78", " 10^81", " 10^84", " 10^87",
   " Vigintinonillion", " 10^93", " 10^96", " Duotrigintillion", " Trestrigintillion" }},
  };
  private static readonly IDictionary<Language, string> Negative = new Dictionary<Language, string>
  {
   { Language.English, "Negative " },
   { Language.Persian, "منهاي " } 
  };
  private static readonly IDictionary<Language, string> Zero = new Dictionary<Language, string>
  {
   { Language.English, "Zero" },
   { Language.Persian, "صفر" } 
  };

  #endregion Fields

  #region Methods (7)

  // Public Methods (5) 

  /// <summary>
  /// display a numeric value using the equivalent text
  /// </summary>
  /// <param name="number">input number</param>
  /// <param name="language">local language</param>
  /// <returns>the equivalent text</returns>
  public static string NumberToText(this int number, Language language)
  {
   return NumberToText((long)number, language);
  }


  /// <summary>
  /// display a numeric value using the equivalent text
  /// </summary>
  /// <param name="number">input number</param>
  /// <param name="language">local language</param>
  /// <returns>the equivalent text</returns>
  public static string NumberToText(this uint number, Language language)
  {
   return NumberToText((long)number, language);
  }

  /// <summary>
  /// display a numeric value using the equivalent text
  /// </summary>
  /// <param name="number">input number</param>
  /// <param name="language">local language</param>
  /// <returns>the equivalent text</returns>
  public static string NumberToText(this byte number, Language language)
  {
   return NumberToText((long)number, language);
  }

  /// <summary>
  /// display a numeric value using the equivalent text
  /// </summary>
  /// <param name="number">input number</param>
  /// <param name="language">local language</param>
  /// <returns>the equivalent text</returns>
  public static string NumberToText(this decimal number, Language language)
  {
   return NumberToText((long)number, language);
  }

  /// <summary>
  /// display a numeric value using the equivalent text
  /// </summary>
  /// <param name="number">input number</param>
  /// <param name="language">local language</param>
  /// <returns>the equivalent text</returns>
  public static string NumberToText(this double number, Language language)
  {
   return NumberToText((long)number, language);
  }

  /// <summary>
  /// display a numeric value using the equivalent text
  /// </summary>
  /// <param name="number">input number</param>
  /// <param name="language">local language</param>
  /// <returns>the equivalent text</returns>
  public static string NumberToText(this long number, Language language)
  {
   if (number == 0)
   {
    return Zero[language];
   }

   if (number < 0)
   {
    return Negative[language] + NumberToText(-number, language);
   }

   return wordify(number, language, string.Empty, 0);
  }
  // Private Methods (2) 

  private static string getName(int idx, Language language, DigitGroup group)
  {
   return NumberWords.Where(x => x.Group == group && x.Language == language).First().Names[idx];
  }

  private static string wordify(long number, Language language, string leftDigitsText, int thousands)
  {
   if (number == 0)
   {
    return leftDigitsText;
   }

   var wordValue = leftDigitsText;
   if (wordValue.Length > 0)
   {
    wordValue += And[language];
   }

   if (number < 10)
   {
    wordValue += getName((int)number, language, DigitGroup.Ones);
   }
   else if (number < 20)
   {
    wordValue += getName((int)(number - 10), language, DigitGroup.Teens);
   }
   else if (number < 100)
   {
    wordValue += wordify(number % 10, language, getName((int)(number / 10 - 2), language, DigitGroup.Tens), 0);
   }
   else if (number < 1000)
   {
    wordValue += wordify(number % 100, language, getName((int)(number / 100), language, DigitGroup.Hundreds), 0);
   }
   else
   {
    wordValue += wordify(number % 1000, language, wordify(number / 1000, language, string.Empty, thousands + 1), 0);
   }

   if (number % 1000 == 0) return wordValue;
   return wordValue + getName(thousands, language, DigitGroup.Thousands);
  }

  #endregion Methods
 }
}



دريافت پروژه كامل به همراه Unit tests مرتبط


۱۳۹۰/۰۶/۱۵

هزينه استفاده از دات نت فريم ورك چقدر است؟


سؤالي از طريق ايميل از من پرسيده شده كه ترجيح مي‌دهم آن‌را به صورت باز در اينجا پاسخ دهم. اگر فرض كنيم همين فردا مجبور شويم براي عمده‌ي كارهاي خود لايسنس تهيه كنيم، آيا مي‌توان از ابزارهاي موجود دات نت در يك شركت تازه تاسيس (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 مي‌توان يافت؟
- اگر به مشكل برخوردم، كسي هست به داد من برسه؟ چه زماني؟! مثلا هفته بعد يا تا آخر امروز؟
- چندتا وبلاگ فعال در اين زمينه موجود است؟ آيا هستند كساني كه در اين زمينه‌ها فعالانه مطلب منتشر كنند؟ اطلاع رساني كنند؟
- اگر كارمند برنامه نويس شركتي امروز قهر كرد، مدير بخش توسعه تا چه زماني مي‌تونه يك نفر رو جايگزين اون كنه؟ مثلا تا آخر ماه يا تا آخر سال؟! اون هم با چه كيفيتي؟ با چه دستمزدي؟
و اينجا است كه وضعيت دات نت در ايران بسيار مطلوب‌تر از موارد مشابه به نظر مي‌رسد. از نظر تعداد كتاب فارسي مهيا، تعداد انجمن، تعداد وبلاگ فعال و غيره.

۱۳۹۰/۰۴/۳۱

بررسي علت CPU Usage بالاي برنامه در حال اجرا


فرض كنيد به يك سرور مراجعه كرده‌ايد و شكايت از CPU Usage مربوط به پروسه w3wp.exe يا همان IIS Worker Process است كه بالاي 90 درصد مي‌باشد. بر روي اين سرور هم هيچ چيز ديگري نصب نيست و مطابق مقررات موجود، قرار هم نيست كه برنامه‌اي نصب شود. اكنون سؤال اين است كه چطور تشخيص مي‌دهيد، كدام قسمت يكي از برنامه‌ها‌ي دات نتي در حال اجرا (در اينجا يكي از برنامه‌هاي ASP.NET هاست شده)، سبب بروز اين مشكل شده است؟ كدام ترد بيشترين زمان CPU را به خود اختصاص داده است؟ چطور بايد خطايابي كرد؟
اولين كاري كه در اين موارد توصيه مي‌شود مراجعه به برنامه‌ي معروف process explorer و بررسي برگه‌ي threads آن است. در اينجا حتي مي‌توان call stacks مرتبط با يك ترد را هم مشاهده كرد. اما ... اين برگه در مورد پروسه‌ها و تردهاي دات نتي، اطلاعات چنداني را در اختيار ما قرار نمي‌دهد.
خوشبختانه امكان ديباگ پروسه‌هاي دات نتي در حال اجرا توسط كتابخانه‌ي MdbgCore.dll پيش بيني شده است. اين فايل را در يكي از مسير‌هاي ذيل مي‌توانيد پيدا كنيد:
C:\Program Files\Microsoft SDKs\Windows\vXYZ\bin\MdbgCore.dll
C:\Program Files\Microsoft SDKs\Windows\vXYZ\bin\NETFX 4.0 Tools\MdbgCore.dll

در ادامه مي‌خواهيم توسط امكانات اين كتابخانه، به stack trace تردهاي در حال اجراي يك برنامه دات نتي دسترسي پيدا كرده و سپس نام متدهاي مرتبط را نمايش دهيم:
using System;
using System.Collections;
using System.Diagnostics;
using Microsoft.Samples.Debugging.MdbgEngine;

namespace CpuAnalyzer
{
class Program
{
static void Main(string[] args)
{
var engine = new MDbgEngine();

var processesByName = Process.GetProcessesByName("MyApp");
if (processesByName.Length == 0)
throw new InvalidOperationException("specified process not found.");
var processId = processesByName[0].Id;

var process = engine.Attach(processId);
process.Go().WaitOne();

foreach (MDbgThread thread in (IEnumerable)process.Threads)
{
foreach (MDbgFrame frame in thread.Frames)
{
if (frame == null || frame.Function == null) continue;
Console.WriteLine(frame.Function.FullName);
}
}

process.Detach().WaitOne();
}
}
}
در اينجا در ابتدا نياز است تا pid يا process-id مرتبط با برنامه در حال اجرا يافت شود. سپس از اين pid جهت اتصال (engine.Attach) به پروسه مورد نظر استفاده خواهيم كرد. در ادامه كليه تردهاي اين پروسه در حال ديباگ ليست شده و سپس MDbgFrameهاي اين ترد بررسي مي‌شوند و نام متدهاي مرتبط در كنسول نمايش داده خواهند شد.
خوب در مرحله بعد شايد بد نباشد كه اين متدها را بر اساس CPU usage آن‌ها مرتب كنيم. به اين ترتيب بهتر مي‌توان تشخيص داد كه كدام متد مشكل ساز بوده است. براي اين منظور بايد به API ويندوز و تابع GetThreadTimes مراجعه كرد و اولين پارامتر ورودي آن، همان thread.CorThread.Handle اولين حلقه مثال فوق مي‌باشد. هر كدام كه جمع KernelTime + UserTime بيشتري داشت، همان است كه مشكل درست كرده است.
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool GetThreadTimes(IntPtr handle, out long creation, out long exit, out long kernel, out long user);
اين مورد را به عنوان تمرين بررسي كرده و ادامه دهيد! همچنين بهتر است جهت دستيابي به اطلاعاتي معتبر، اولين حلقه برنامه فوق، حداقل 10 بار اجرا شود تا اطلاعات آماري بهتري را بتوان ارائه داد. البته در اين حالت نكته‌ي زير بايد رعايت شود:
for (int i = 0; i < 10; i++)
{
foreach (MDbgThread thread in (IEnumerable)process.Threads)
{
//...
}
process.Go();
Thread.Sleep(1000);
process.AsyncStop().WaitOne();
}

در كل اين مثال جاي كار زياد دارد. براي مثال طراحي يك رابط كاربري براي آن و نمايش جزئيات بيشتر. به همين منظور حداقل سه پروژه مشابه را مي‌توان نام برد:

۱۳۹۰/۰۴/۲۳

چك ليست تهيه يك گزارش خوب


مشخصات يك گزارش خوب عموما به شرح زير است:

1- بايد هر سطر گزارش شماره رديف داشته باشد. (بايد امكان ارجاع به هر سطر در صورت بروز مشكل ميسر باشد)
2- بايد در هر صفحه، شماره صفحه و تعداد كل صفحات ذكر شود. (اگر چاپ شد بر اين اساس بتوان ارتباط بين صفحات را يافت)
3- در هر صفحه بايد تاريخ و ساعت روز تهيه گزارش حتما ذكر شود. (بعدا جهت رفع اختلافات لازم مي‌شود. مثلا مي‌گويند اين عدد اشتباه است. اما واقعا اين عدد در زمان تهيه گزارش درست بوده، اما الان بر اساس اطلاعات جديد ... بله ... چيزي ديگري است، يا به قول آن‌ها اشتباه است)
4- در پايان هر صفحه، يك سري از ستون‌هاي عددي بايد جمع كل داشته باشد.
5- در ابتداي هر صفحه بايد "نقل از صفحه قبل" يا همان سطر جمع كل صفحه قبل ذكر شود.
6- هدر گزارش بايد در تمام صفحات تكرار شود. (بايد مشخص باشد اين صفحه گزارش كه الان به دست من رسيده متعلق به كجاست، عنوانش چيست حداقل؟)
7- سر ستون‌ها هم بايد در هر صفحه تكرار شوند. (مثلا الان صفحه 20 يك گزارش پيش روي شما است. بايد بدانيد معناي اين ستون سوم ظاهر شده در گزارش چيست)
8- تمام اعداد موجود در گزارش بايد جداكننده سه رقمي داشته باشند. (خواندن 4446327531 ساده‌تر است يا خواندن 4,446,327,531 ؟)
9- تمام اعداد گزارش بايد فارسي نمايش داده شوند. (اين مورد را مي‌شود با فونت‌هاي دستكاري شده كه احتمالا شما هم يك دوجين از آن‌ها را داريد، حل كرد. فونت‌هايي كه با يك فونت اديتور مثل برنامه معروف FontCreator ويرايش شده و بجاي اعداد انگليسي آن‌ها، همان اعداد فارسي قرار گرفته‌اند)

۱۳۹۰/۰۴/۰۷

رديابي واژه‌هاي كليدي در سايت‌هاي اجتماعي


فرض كنيد مي‌خواهيد واژه‌ KeyWord را در يك سري سايت اجتماعي از طريق Google reader تحت نظر داشته باشد كه كلا اوضاع از چه قرار است و علاقمند‌ي‌هاي عموم در اين زمينه چيست؟ آخرين مطالب به اشتراك گذاشته شده كدام‌ها هستند و در اين زمينه خاص، دنيا دست كيست؟

فيد تحت نظر قرار دادن يك واژه كليدي در
  • كليه وبلاگ‌هاي سايت wordpress.com :
http://en.wordpress.com/tag/KeyWord/feed/
  • سايت twitter.com: (پيدا كردن فيد اين يكي آنچنان واضح نيست چون به نظر اخيرا توئيتر فيدها رو حذف يا مخفي كرده)
http://search.twitter.com/search.atom?q=KeyWord

  • سايت delicious.com :
http://feeds.delicious.com/v2/rss/tag/KeyWord?count=15

  • سايت friendfeed.com :
http://friendfeed.com/search?q=KeyWord&format=atom

  • سايت stackoverflow.com :
http://stackoverflow.com/feeds/tag/KeyWord


شما هم اگر مورد خاصي را مد نظر داريد كه در بالا ذكر نشده، لطفا مطرح كنيد.

۱۳۹۰/۰۳/۲۶

مشكلات نصب به روز رساني‌هاي اخير


مشكل نصب به روز رساني‌هاي دات نت فريم ورك
اگر احتمالا آپديت‌هاي اخير دات نت فريم ورك را نتوانسته‌ايد نصب كنيد و هربار پس از ري استارت كامپيوتر مجددا سر و كله برنامه نصاب پيدا مي‌شود و نهايتا پيغام failed را دريافت مي‌كنيد، متاسفانه فقط يك راه حل دارد. حذف موارد موجود و نصب مجدد نگارش جديد آن‌ها. براي حذف كليه نگارش‌هاي دات نت فريم ورك از برنامه زير استفاده كنيد:


سپس بهتر است از نصاب نگارش وب دات نت فريم ورك استفاده كنيد. از اين لحاظ كه تمام به روز رساني‌ها را به همراه دارد و متفاوت است با نسخه‌ي آفلاين آن.


مشكل نصب به روز رساني‌هاي سيلورلايت
اگر هنگام نصب به روز رساني جديد سيلورلايت هر بار پيغام silverlight.msi File Missing را دريافت مي‌كنيد، مسير زير را از رجيستري ويندوز حذف كنيد. سپس به روز رساني سيلورلايت بدون مشكل نصب خواهد شد:
HKEY_CLASSES_ROOT / installer / products / D7314F9862C648A4DB8BE2A5B47BE100


پ.ن.
من هر دو مشكل را با ويندوز سرور 2003 داشتم.

۱۳۹۰/۰۳/۱۷

به روز رساني جديد دات نت 4


به روز رساني جديدي جهت رفع 35 مشكل در دات نت 4 ، روز قبل ارائه شده است كه از آدرس ذيل قابل دريافت مي‌باشد. اين به روز رساني شامل كليه موارد برطرف شده در به روز رساني‌هاي قبلي نيز مي‌باشد:

۱۳۹۰/۰۳/۱۲

مجوز WTFPL


در بين مجوز‌هاي سورس باز، يكي از اون‌ها كه اتفاقا مورد پذيرش FSF هم هست، عنوان جالبي داره كه ترجمه‌اش به فارسي مي‌شود: "برو هر غلطي كه دلت مي‌خواد باهاش بكن!" يا WTFPL = Do What The F.u.c.k You Want To Public License
نگارش يك اين مجوز توسط Banlu Kemiyatorn نويسنده برنامه Window maker در سال 2000 ارائه شده و در سال 2007 توسط مدير پروژه تيم Debian نگارش دوم آن ارائه گرديده است!
اين مجوز به شما اجازه هر نوع تغيير يا هر روش توزيعي را در مورد برنامه‌ي مورد نظر مي‌دهد.
ترجمه اين مجوز هم به زبان فارسي به صورت زير است:

"
مجوز برو هر غلطي كه دلت مي‌خواد بكن!
نگارش 2، دسامبر 2004

هر كسي مجاز است اين مستند را كپي يا توزيع كند با اين شرط كه اگر تغييري در اصل آن داده شد، نامش را تغيير دهد.
شروط اصلي اين مجوز به شرح ذيل اعلام مي‌گردد:
0- فقط برو هر غلطي كه دلت مي‌خواد باهاش بكن

"

البته شايد اين سؤال پيش بياد كه اين موارد به چه دليلي اضافه شده؟ احتمالا شايد شنيده باشيد كه عده‌اي GPL‌ رو يك نوع سرطان مي‌دونند؛ از اين لحاظ كه اگر طرف اون رفتيد بايد كل برنامه خودتون رو سورس باز ارائه بديد. به همين جهت كساني كه كار تجاري انجام مي‌دهند از طرف سورس‌هاي پروژه‌هاي مبتني بر GPL رد هم نمي‌شوند. در مقابل آن مجوزهايي مانند BSD يا MIT ملاحظات GPL را ندارند (+). در كل GPL تا به امروز لينوكس را زنده نگه داشته است.

۱۳۹۰/۰۲/۰۲

ظهور ميكرو ORMs


پس از "معرفي Microsoft.Data.dll يا WebMatrix.Data.dll" كه يك كتابخانه‌ي سورس بسته و همچنين مخصوص وب ماتريكس مي‌باشد، اين ايده توسط ساير برنامه نويس‌ها دنبال و تبديل به ORMs جديدي با كمتر از 400 سطر كد شده است كه به Micro ORMs هم شهرت يافته‌اند.
در اينجا شما هنوز هم كاملا با SQL سر و كار داريد اما با امكان استفاده بسيار ساده‌تر از پارامترها و همچنين بكارگيري قابليت‌هاي جديد dynamic معرفي شده در دات نت 4 . براي مثال:

Dapper
var guid = Guid.NewGuid();
var customer = connection.ExecuteMapperQuery<customer>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid });

Massive
var tbl = new Products();
var products = tbl.All(where: "CategoryID = @0 AND UnitPrice &gt; @1", orderBy: "ProductName", limit: 20, args: 5,20);

Massive توسط آقاي راب كانري كه قبلا ORM ديگري را به نام ساب سونيك ايجاد كرده بود، تهيه شده و Dapper توسط تيم سايت StackOverflow جهت مواردي خاصي كه استفاده از ORMs (از LINQ to SQL استفاده مي‌كنند) هزينه زيادي داشته، مورد استفاده قرار مي‌گيرد. در همان صفحه اصلي پروژه، يك سري آمار و ارقام از ديد مقايسه كارآيي با ساير ORMs نيز ذكر شده‌اند.
حتي اگر قصد استفاده از آن‌ها را هم نداشته باشيد مطالعه كد آن‌ها از ديدگاه كاربردهاي عملي قابليت‌هاي پوياي زبان، بسيار آموزنده هستند.

۱۳۹۰/۰۱/۳۰

رادار فناوري اطلاعات


احتمالا يك سري نمودار مانند اين را ديده باشيد كه هر از چندگاهي براي زبان‌هاي برنامه نويسي از ديدگاه محبوبيت تعيين رتبه مي‌كنند. البته اين آمار با آنچه كه در سايت پر بازديد stackoverflow در جريان است عموما در تناقض است؛ از اين لحاظ كه برنامه نويسي با سؤال مواجه نمي‌شود كه كار نمي‌كند!
بر اين اساس عده‌اي آمار و اطلاعات سايت stackoverflow را هر از چندگاهي آناليز مي‌كنند تا متوجه شوند هم اكنون كدام زبان‌ها يا فريم ورك‌ها بيشتر مورد استفاده هستند؛ براي مثال:
  • كداميك از فريم ورك‌هاي وب بيشتر مورد استفاده هستند؟ (+)
  • كداميك از زبان‌هاي برنامه نويسي بيشتر محبوب هستند؟ (+) و (+) (محبوبيت در اينجا به معناي تعداد سؤال پرسيده شده است نه علاقه شخصي)
  • همين سوال بر اساس مسابقه هوش مصنوعي گوگل: (+) و (+)

اين‌‌ها يك روي سكه هستند؛ روي ديگر آن هم به اين صورت است كه "الان واقعا اون ور آ‌ب‌ها چه خبره؟!" صرف نظر از علاقه شخصي من كه بخواهند بر اساس آن نمودار رسم كنند يا تعداد سؤالات پرسيده شده در يك انجمن، نظر كارشناسان امر در اين باره چيست؟ بر همين اساس شركت ThoughtWorks مدتي است يك سري آمار را بر اساس وضعيت شركت‌هاي بزرگ، بازار و علاقمند‌ي‌هاي جاري آن‌ها منتشر مي‌كند كه از آدرس زير قابل دريافت هستند:



۱۳۸۹/۱۲/۰۵

محصولات آموزشي سايت Tekpub


سايت Tekpub محصولات آموزشي خودش رو به مدت فقط 24 ساعت به صورت رايگان در دسترس علاقمندان قرار داده. شامل دوره‌هاي كامل ASP.NET MVC ، Entity framework و غيره. بشتابيد!



۱۳۸۹/۱۱/۰۵

OneNote و مصرف بالاي RAM و CPU


از برنامه OneNote زياد استفاده مي‌كنم. عموما براي يادداشت برداري از سايت‌ها؛ فقط كافي است يك صفحه از مرورگر خودتون را با Ctrl+A انتخاب و با Ctrl+C در حافظه كپي كنيد. سپس با Ctrl+V در OneNote ، كل صفحه با همان فرمت اصلي و تمام تصاوير، جداول و غيره ذخيره خواهد شد. همچنين در OneNote 2010، دريافت تصاوير از سايت‌ها به صورت asynchronous است (برخلاف نگارش 2007 آن) و حين دريافت تصاوير برنامه متوقف نمي‌شود.

اما اگر سرويس Windows search كه كار indexing را انجام مي‌دهد خاموش باشد:
  • احتمالا OneNote شما بالاي 400 مگ رم مصرف خواهد كرد.
  • مرتبا هنگ مي‌كند.
  • عموما CPU Usage ايي بالاي 50 درصد به صورت مداوم خواهيد داشت.
  • جستجوي آن ديگر درست كار نمي‌كند و بسيار بسيار كند خواهد بود.
و اگر سرويس ياد شده روشن باشد،‌ همه چيز عادي است، از مصرف رم تا CPU و غيره.

۱۳۸۹/۱۰/۲۰

يافتن نام رشته‌اي كامل يك كلاس در دات نت


دو تنظيم زير را در نظر بگيريد:
<add key="nhibernate-logger" value="NHibernate.Helper.Logging.LoggerFactory, NHibernate.Helper" />
و يا
<add name="StaticContentCacheModule" type="StaticContentCacheModule.StaticCache, StaticContentCacheModule"/>
اين نوع موارد را در فايل‌هاي app.config و يا web.config زياد مي‌توان يافت.
الان فرض كنيد كلاس StaticCache مربوط به StaticContentCacheModule فرضي فوق را به صورت دستي به برنامه‌ي خود اضافه كرده‌ايد. همچنين سطر فوق را نيز بدون هيچ تغييري در قسمت http modules مربوط به web.config برنامه معرفي نموده‌ايد. برنامه را اجرا مي‌كنيد، اما ماژول ذكر شده كار نمي‌كند! چرا؟
چون نام رشته‌اي متناظر با كلاس StaticCache ايي كه اكنون به پروژه‌ي خود اضافه كرده‌ايد، با توجه به فضاهاي نام پروژه‌ي جديد، كاملا دگرگون شده است. بنابراين، سؤال مهم اينجا است كه اين نام را بر اساس تنظيمات پروژه‌ي جاري چگونه مي‌توان يافت؟
خوشبختانه دات نت فريم ورك، ابزاري توكار را براي توليد اين نام رشته‌اي، به همراه دارد:
class Test
{
static void Main()
{
string name = typeof(System.Data.DataView).AssemblyQualifiedName;
Console.WriteLine(name);
}
}
خاصيت AssemblyQualifiedName ذكر شده در مثال فوق، دقيق‌ترين نامي است كه مي‌توانيد در پروژه‌ي خود استفاده نمائيد.
خروجي اين مثال جهت نمايش نام رشته‌اي معادل كلاس System.Data.DataView به صورت زير است:
System.Data.DataView, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

سؤال: از كجا متوجه شوم كه رشته‌ي فوق واقعا كار مي‌كند؟
مقدار متغير name مثال فوق بايد پس از بكارگيري در متد Type.GetType ، حاصلي غير null را بازگشت دهد.
var name = typeof(System.Data.DataView).AssemblyQualifiedName;
var type = Type.GetType(name);
اگر حاصل نال بود، يعني همان مشكلي كه در ابتداي مطلب ذكر شد: ماژول مشخص شده در web.config برنامه توسط رشته‌ي مورد نظر كار نخواهد كرد.

نكته: اگر قصد معرفي اسمبلي ديگري را به برنامه داريد و اين اسمبلي امضاي ديجيتال دارد (strong name signature)، بايد تمام اطلاعات حاصل را ذكر كنيد (مانند مثال فوق كه شامل Version ، Public key token و غيره است). در غير اينصورت (عدم وجود امضاي ديجيتال) ذكر دو قسمت اول خروجي خاصيت AssemblyQualifiedName كافي خواهند بود.

۱۳۸۹/۱۰/۱۴

وضعيت فناوري‌هاي مرتبط با دات نت از ديدگاه مرگ و زندگي!


مطلبي كه در ذيل آورده شده صرفا يك برداشت شخصي است بر اساس نقل قول‌ها و بررسي وضعيت اعضاي تيم‌هاي مرتبط با فناوري‌هاي مختلف بكار گرفته شده در دات نت فريم ورك و ... نه رسمي!

ADO.NET ، DataSet ، DataTable و امثال آن: مرده! (مرده به معناي اينكه ديگر توسعه‌ي جدي نخواهد يافت)
ADO.NET‌ اولين فناوري دسترسي به داده‌ها در دات نت فريم ورك بود/است. مدل طراحي آن هم بر اساس امكانات زبان‌هاي آن زمان (زمان شروع به كار دات نت) بود (و تا دات نت 4 هم تغيير عمده‌اي نكرده). براي مثال در زمان ارائه اولين نگارش آن خبري از Generics نبود (در دات نت 2 اضافه شد)؛ يا LINQ وجود نداشت (در دات نت سه و سه و نيم اضافه و تكميل شد). به همين جهت طراحي آن در حال حاضر (با وجود دات نت 4) بوي ماندگي مي‌دهد (مانند استفاده از ديتاست و ديتاتيبل) و با ORM هاي مايكروسافت جهت استفاده از امكانات Generics و LINQ جايگزين شده‌ است.
البته اين مورد تنها مورد مرده‌اي است كه "بايد" ياد گرفت؛ مهم نيست كه ORMs ارائه شده‌اند. مهم اين است كه زير ساخت تمام ORM هاي نوشته شده براي دات نت همين ADO.NET خام است.


LINQ to SQL : مرده!
مايكروسافت با اين فناوري ORM هاي خودش را شروع كرد اما بعد از مدتي ديد كه بهتر است يك نسخه‌ي عمومي‌تر با پشتيباني از بانك‌هاي اطلاعاتي ديگر مانند اوراكل، MySQL و غيره را نيز ارائه دهد. همينجا بود كه آن‌را خيلي ساده با Entity framework جايگزين كرد و در roadmap ارائه شده صراحتا EF به عنوان راه حل توصيه شده دسترسي به داده‌هاي مايكروسافت اعلام شده است (+). حالا اين وسط ديگر مهم نيست شما پروژه نوشته بوديد يا هر چي. ديگر منتظر تغييرات خاصي در LINQ to SQL نباشيد. فقط يك سري رفع باگ و نگهداري پروژه را شاهد خواهيد بود. البته در همان زمان خيلي زود تكذيب كردند كه LINQ to SQL مرده اما براي نمونه آقاي Damien كه عضو اصلي تيم LINQ to SQL بودند، اكنون در تيم XBOX مشغول به كار هستند! (+) تو خود شرح مفصل بخوان از اين مجمل!

ضمنا اين رو هم در نظر داشته باشيد كه LINQ != LINQ to SQL ؛ به عبارتي LINQ به خودي خود فقط يك language feature است.


Windows Forms يا به اختصار WinForms : مرده!
به نظر مظلوم‌تر از اين يكي در دات نت يافت نمي‌شود! همين چند وقت پيش يكي از اعضاي مايكروسافت اين نظر سنجي رو برگزار كرده بود كه "ما چكار كنيم كه شما راحت‌تر از WinForms به WPF مهاجرت كنيد؟!" (+)
در قاموس WPF ، ويندوز فرمز يعني Canvas panel ؛ به عبارتي صلب‌ترين حالت طراحي رابط كاربري و اين انتقال و مهاجرت هرچند براي كساني كه عمري را روي آن گذاشته‌اند، دردناك خواهد بود اما با وجود توانايي‌هاي WPF چيزي را از دست نخواهند داد. سيستم Layout (طرح بندي) در WinForms و همچنين دلفي، بر اساس قراردهي اشياء در مختصات مطلقي در صفحه است. مثلا اين دكمه‌ي خاص در آن نقطه‌ي معلوم قرار مي‌گيرد و همين. اين روش طرح بندي يكي از چندين روش طرح بندي در WPF است كه اصطلاحا Canvas نام دارد. توصيه اكيد و مطلق در WPF آن است كه از Canvas فقط براي طراحي اشياء گرافيكي پيچيده استفاده كنيد و نه طراحي رابط كاربر. چرا؟ چون براي مثال در Silverlight كه برادر كوچكتر WPF محسوب مي‌شود، رابط كاربري آن بايد بتواند همانند HTML انعطاف پذير باشد و با اندازه‌هاي مختلف مرورگر يا اندازه‌ي قلم‌هاي بزرگتر هماهنگ شده و مقاومت كند، بدون اينكه از ريخت بيفتد و اين مورد را ساير سيستم‌هاي طرح بندي رابط كاربر (منهاي Canvas يا همان سيستم طرح بندي WinForms) ارائه مي‌دهند. مورد ديگري كه در WPF و Silverlight بسيار حائز اهميت است ، Content Controls مي‌باشد. چقدر خوب مي‌شد بتوان داخل يك كنترل، كلا يك سيستم طرح بندي را تعريف كرد و اشياء دلخواهي را داخل آن قرار داد. مثلا ToolTip پيش فرض وجود دارد. بسيار هم خوب. بنده علاقه دارم، متن عنوان آن ضخيم باشد. كنار آن يك تصوير كوچك و در سمت چپ آن متن قرار گيرد. براي انجام اينكار در WPF لازم نيست تا شما منتظر نگارش بعدي دات نت باشيد كه دست اندركاران مربوطه با افتخار در يك سند 50 صفحه‌اي توضيح دهند كه چگونه مي‌توان اينكار را انجام داد. يك سيستم طرح بندي را اضافه كنيد. موارد ذكر شده را در آن تعريف كنيد. بدون استفاده از هيچ نوع كامپوننتي يا بدون منتظر ماندن تا نگارش بعدي اين محصولات، به مقصود خود رسيده‌ايد.


ASP.NET Web forms : داره نفس‌هاي آخرش رو مي‌كشه!
از زمانيكه ASP.NET MVC آمد نسخه‌ي Web forms تقريبا فراموش شد. به وبلاگ اسكات گاتري يا Haacked و ساير اعضاي اصلي دات نت كه مراجعه كنيد در سه سال اخير در حد تعداد انگشتان يك دست هم در مورد Web forms مطلب ننوشته‌اند. تمام تمركز و نوآوري‌ها بر روي MVC متمركز شده و حتي در نسخه‌ي 4 دات نت هم فقط يك سري صافكاري مختصر را در Web forms شاهد بوديم مثلا نام كنترل‌ها را خودتان هم در زمان رندر نهايي مي‌توانيد تعيين كنيد! يا لطفا كردند و قسمتي از url routing موجود در ASP.NET MVC را به ASP.NET web forms 4 هم قرض دادند (اين مورد شايد مهم‌ترين تغيير قابل ذكر در ASP.Net web forms 4 است).
البته اين رو هم اضافه كنم كه ASP.NET MVC‌ واقعا قابل احترام است؛ هدف از آن جدا سازي لايه‌هاي برنامه با الگوهاي استاندارد صنعتي (و نه هر روش برنامه نويسي چند لايه من درآوردي)، ترويج كد نويسي بهتر، ترويج Unit testing ، رفع يك سري مشكلات ASP.NET Web forms (مثلا از ViewState هاي حجيم ديگر خبري نيست) و امثال آن است.
براي نمونه توجه شما را به مطلبي كه آقاي Dino Sposito در مورد ASP.NET Webforms نوشته جلب مي‌كنم: (+)
به صورت خلاصه ايشان عنوان كرده زمان طراحي ASP.NET Webforms در 10 سال قبل، هدف ما انتقال ساده‌تر برنامه نويس‌هاي VB به محيط وب بود. به همين جهت دست به اختراع postback ، viewState ، كنترل‌هاي سمت سرور و غيره زديم. (بنابراين تاكيد تمام اين‌ها اين است كه webforms فناوري دهه قبل "بود" و الان بنابر نيازهاي جديد دست به طراحي مجدد زده‌ايم)

در مورد "پايان پروژه ASP.NET Ajax Control Toolkit" هم قبلا مطلب نوشته بودم و اين يكي واقعا official است!


و در پايان بايد متذكر شد كه فلان فناوري مرده يا داره نفس‌هاي آخرش رو مي‌كشه اصلا مهم نيست. هنوز هم هستند سازمان‌هايي كه برنامه‌هاي نوشته شده با ASP كلاسيك (نگارش قبل از ASP.NET Web forms) خود را دارند و خيلي هم از آن راضي هستند!
اين موارد رو از اين جهت نوشتم كه اگر مي‌خواهيد تازه به اين جمع وارد شويد دقيقا بدانيد بايد روي چه مواردي بيشتر وقت بگذاريد و يادگيري كداميك صرفا اتلاف وقت خواهند بود (مثلا EF بر LINQ to SQL ارجح است و اگر امروز مي‌خواهيد شروع كنيد با EF شروع كنيد، يا ديگر كم كم با وجود WPF ، بازار كاري براي WinForms نخواهد بود).

۱۳۸۹/۰۹/۲۴

پايان پشتيباني از دات نت فريم ورك 3 و سه و نيم


پشتيباني از دات نت فريم ورك‌هاي سه و سه و نيم دقيقا در تاريخ "سه‌شنبه 23 فروردين 1390" پايان خواهد يافت. توصيه مايكروسافت ارتقاء برنامه‌هاي موجود به دات نت فريم ورك سه و نيم، سرويس پك يك و يا دات نت 4 است. طول عمر دات نت فريم ورك سه و نيم، سرويس پك يك به صورت Component محاسبه مي‌شود؛ به اين معنا كه اگر دقت كرده باشيد اين نگارش به صورت پيش فرض جزئي از ويندوز 7 يا ويندوز سرور 2008 است. بنابراين تا زمانيكه اين دو سيستم عامل توسط مايكروسافت پشتيباني مي‌شوند، اجزاي آن‌ها نيز همانند دات نت فريم ورك سه و نيم، سرويس پك يك، پشتيباني خواهند شد.
جدول كامل طول عمر نگارش‌هاي مختلف دات نت فريم ورك را در اينجا مي‌توانيد ملاحظه كنيد.

۱۳۸۹/۰۷/۰۸

برنامه‌ي ++ Notepad و syntax highlighting فايل‌هاي دات نتي


برنامه‌ي ++ Notepad به عنوان يك اديتور رايگان، سبك و بسيار سريع به همراه ارائه‌ي syntax highlighting عالي، يكي از ويرايشگرهاي محبوب برنامه نويس‌ها (در هر گرايش و صنفي) به شمار مي‌رود. اكثر فايل‌هاي مرتبط با دات نت فريم ورك هم منهاي فايل‌هاي سورس‌ها با پسوند cs و vb و امثال آن، دقيقا از نوع XML هستند؛ براي مثال: xaml, config, edmx, csproj و بسياري موارد ديگر. اين پسوندها به صورت پيش فرض در برنامه‌ي ++ Notepad جهت اعمال syntax highlighting تعريف نشده‌اند و براي اضافه كردن آن‌ها كافي است به صورت زير عمل كرد:
به منوي Settings گزينه‌ي Style configurator مراجعه كنيد. سپس در قالبي كه آن‌را انتخاب كرده‌ايد، زبان XML را انتخاب كرده و فيلد User ext را تكميل كنيد (شكل زير):