نظرات مطالب
الگوی طراحی Builder همراه با اصول Interface Segregation
مشکل در فراموش کردن و عدم تامین و مقدار دهی برخی از پروپرتی‌ها بود.
ولی در پایان کار همچنان مشکل مطرحه حل نشد.
اگر برنامه نویس یکی از متدها را را فراموش کند چی؟ مثلا WithSurename("Karimi")
با طلب کردن مقادیر در سازنده کلاس میتوان برنامه نویس را موظف به تامین همه داده‌ها کرد ولی بنظر این موضوع در خودکارسازی تزریق وابستگیها خوشایند رفتار نخواهد کرد.
نظرات مطالب
توزیع پروژه‌های ASP.NET MVC بدون ارائه فایل‌های View آن

سلام آقای نصیری.من نسخه 2.1.2 Razor Generator رو نصب کردم.اما دستور enable-razorgenerator بدون دادن هیچ خطایی انجام می‌شود اما فایلهای  Cs مربوط به View‌ها تولید نمیشه و وقتی روشون Run Custom Tool رو می‌زنم این پیغام میاد.ممنون اگه راهنماییم کنید.

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

مرحله جذب:

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

مرحله انتخاب:

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

مواردی که در آگهی استخدام شرکت دلفین رعایت شده بود:

»ذکر نام شرکت

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

»ذکر آدرس و شماره تماس:

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

» ذکر شرایط استخدام

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

»ذکر شرایط تخصصی متقاضیان کار:

در بخش به صورت کامل شرایط تخصصی و مهارتی افراد مورد بررسی قرار گرفته بود. در یک نگاه خوب به نظر می‌رسید ولی اگر با دقت به این بخش نگاه کنید متوجه خواهید شد به دلیل عدم نگارش صحیح موارد مورد نیاز، کمتر کسی دارای این همه توانایی است آن هم به صورت تسلط کامل. استفاده از واژه تسلط کامل باید با احتیاط انجام شود. برای مثال تسلط کامل بر VB.NET , C#.NET Windows Application . بهتر بود از یا استفاده می‌شد. به این صورت " تسلط بر VB.NET یا C#.NET  در Windows Application"

» ذکر اولویت ها

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

»ذکر آدرس وب سایت شرکت:

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

مواردی که در آگهی استخدام شرکت دلفین رعایت نشده بود:

»عدم توازن بین عنوان آگهی با محتوای آن :

در عنوان آگهی ذکر شده بود "برنامه نویس تحت وب" در حالی که در شرایط تخصصی، موردی به عنوان تسلط کامل بر برنامه نویس تحت ویندوز ذکر شده  آن هم با دو زبان Vb.Net و C#.Net

آیا منظور از تسلط کامل بر مدیریت بانک اطلاعاتی SqlServer همان DBA است؟ اگر پاسخ مثبت است در این صورت چند نفر واجد شرایط را می‌توان پیدا کرد که هم در سطح DBA باشند و هم در سطح یک برنامه نویس سطح بالا؟ اگر پاسخ منفی است بهتر بود از واژه داشتن تجربه در زمینه مدیریت بانک اطلاعاتی یا حتی آشنایی با مدیریت بانک‌های اطلاعاتی استفاده می‌شد.

مورد دیگری که تا حدودی باعث سردرگمی می‌شد این است که نیاز به تسلط کامل به Asp.Net Web Form و هم چنین به Asp.Net MVC است. چرا هردو، آن هم در سطح تسلط کامل؟

در بخش اولویت‌ها موردی ذکر شد با عنوان آشنایی با کامپوننت‌های برنامه نویسی نظیر DevExpress و Telerik  و Kendo. آیا منظور آشنایی با تمام این موارد بوده است یا فقط یکی از آن ها؟

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

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

مطالب
آشنایی با Contained Databases در SQL Server 2012
مقدمه:
بعضی وقت‌ها به هر دلیلی لازم است پایگاه داده برنامه هایمان را به سرور دیگری انتقال دهیم . برخلاف Oracle که انتقال پایگاه داده به سرور دیگر کار مشکل و تخصصی می‌باشد در SQL Server براحتی با یک Detach و Attach مجدد این انتقال انجام خواهد شد. اما اطلاعات Logins در پایگاه داده Master  سرور ذخیره شده است و با فایل پایگاه داده انتقال نمی‌یابد و به هیمن خاطر برخی مواقع پس از Attach پایگاه داده با پیغام The database is not accessible یا Cannot open user default database مواجع خواهیم شد که مشکل بخاطر همین نبود کاربران سرور قبلی و Owner متفاوت پایگاه داده می‌باشد که با استفاده از رویه ذخیره شده sp_change_users_login این مشکل قابل حل می‌باشد اما در SQL Server 2012 راحل بهتری فراهم شده است.

Contained Databases در Sql Server 2012
یکی از امکانات اضافه شده در SQL Server 2012  امکان Contained Databases  هست که برای حل همین مشکل و رفع کامل وابستی پایگاه داده با Instance نصب شده و خاصیت قابل حمل کامل database‌ها می‌باشد. در ادامه نحوه استفاده از این امکان را بررسی خواهیم کرد:
  1. فعال کردن خاصیت Contained Databases 

    قبل از استفاده از Contained Databases می بایست این امکان را فعال کرد. برای این کار می‌توانید از SQL Server Management Studio یا T-SQL commands استفاده نمایید. بر روی نام Instance راست کلیت کنید و گزینه Properties را انتخاب نمایید. از گزینه Advanced که در شکل زیر مشاهده می‌نمایید خاصیت Enable Contained Databases را بر روی True قرار دهید.

    یا می‌توایند از sp_configure این کار را انجام دهید.دستورات زیر این موضوع را نشان می‌دهد.
    sp_configure 'show advanced options',1
    GO
    RECONFIGURE WITH OVERRIDE
    GO
    sp_configure 'contained database authentication',1
    GO
    RECONFIGURE WITH OVERRIDE
    GO

  2. ایجاد یا تغییر یک پایگاه داده از نوع Contained Databases

    برای ایجاد یک پایگاه داده با این خاصیت یا تغییر پایگاه داده موجود کافیست مقدار گزینه Containment type را بر روی Partial قرار دهید. برای پایگاه داده موجود از پنجره Properties پایگاه داده صفحه Options را انتخاب کنید.


  3. ایجاد یک کاربر برای پایگاه داده Contained Databases

    برای تعریف یک کاربر در سطح پایگاه داده پوشه Security پایگاه داده خود را باز کنید بر روی پوشه Users راست کیلک و گزینه New User را انتخاب نمایید از گزینه User type که در شکل زیر نشان داده شده است SQL user with password را انتخاب نمایید و نام کاربر و رمز عبور و تکرار آن را وارد نمایید. کاربر ایجاد شده در سطح پایگاه داده می‌باشد و با انتقال به سرور دیگر نیر قابل دسترسی می‌باشد.

  4.  اتصال به پایگاه داده Contained Databases

    برای اتصال به پایگاه داده کافیست در حالت SQL Server Authentication نام کاربری و رمز عبور جدید را وارد و گزینه Options  را انتخاب و از برگه Additional Connection Parameters نام پایگاه داده مورد نظر را مانند شکل زیر وارد نمایید پس از ورود تنها پایگاه داده خود را مشاهده می‌نمایید. یکی از کاربرهای این قابلیت برای مدیران سرور پایگاه داده می‌باشد که بدون استفاده از مجوز sysadmin  به کاربران اجازه دسترسی را می‌دهد.



نظرات مطالب
مقابله با XSS ؛ یکبار برای همیشه!
طول عمر HttpModule با طول عمر HttpApplication یکی است. به این معنا که تنها یک وهله از آن در زمان آغاز برنامه وب تولید و این وهله به صورت خودکار در زمان پایان عمر برنامه وب (ری استارت شدن سرور، recycle شدن آن توسط IIS و مواردی از این دست)، dispose خواهد شد. بنابراین ضرورتی به پیاده سازی متد Dispose در اینجا وجود ندارد.
اگر این مدیریت طول عمر خودکار نمی‌بود، بله ... بهتر بود که اینکار انجام می‌شد.
مطالب
تهیه XML امضاء شده جهت تولید مجوز استفاده از برنامه
اگر به فایل مجوز استفاده از برنامه‌‌ای مانند EF Profiler دقت کنید، یک فایل XML به ظاهر ساده بیشتر نیست:
<?xml version="1.0" encoding="utf-8"?>
<license id="17d46246-a6cb-4196-98a0-ff6fc08cb67f" expiration="2012-06-12T00:00:00.0000000" type="Trial" prof="EFProf">
  <name>MyName</name>
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <Reference URI="">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <DigestValue>b8N0bDE4gTakfdGKtzDflmmyyXI=</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>IPELgc9BbkD8smXSe0sGqp5vS57CtZo9ME2ZfXSq/thVu...=</SignatureValue>
  </Signature>
</license>
در این فایل ساده متنی، نوع مجوز استفاده از برنامه، Trial ذکر شده است. شاید عنوان کنید که خوب ... نوع مجوز را به Standard تغییر می‌دهیم و فایل را ذخیره کرده و نهایتا استفاده می‌کنیم. اما ... نتیجه حاصل کار نخواهد کرد! حتی اگر یک نقطه به اطلاعات این فایل اضافه شود، دیگر قابل استفاده نخواهد بود. علت آن هم به قسمت Signature فایل XML فوق بر می‌گردد.
در ادامه به نحوه تولید و استفاده از یک چنین مجوزهای امضاء شده‌ای در برنامه‌های دات نتی خواهیم پرداخت.


تولید کلیدهای RSA

برای تهیه امضای دیجیتال یک فایل XML نیاز است از الگوریتم RSA استفاده شود.
برای تولید فایل XML امضاء شده، از کلید خصوصی استفاده خواهد شد. برای خواندن اطلاعات مجوز (فایل XML امضاء شده)، از کلیدهای عمومی که در برنامه قرار می‌گیرند کمک خواهیم گرفت (برای نمونه برنامه EF Prof این کلیدها را در قسمت Resourceهای خود قرار داده است).
استفاده کننده تنها زمانی می‌تواند مجوز معتبری را تولید کند که دسترسی به کلیدهای خصوصی تولید شده را داشته باشد.
        public static string CreateRSAKeyPair(int dwKeySize = 1024)
        {
            using (var provider = new RSACryptoServiceProvider(dwKeySize))
            {
                return provider.ToXmlString(includePrivateParameters: true);
            }
        }
امکان تولید کلیدهای اتفاقی مورد استفاده در الگوریتم RSA، در دات نت پیش بینی شده است. خروجی متد فوق یک فایل XML است که به همین نحو در صورت نیاز توسط متد provider.FromXmlString مورد استفاده قرار خواهد گرفت.


تهیه ساختار مجوز

در ادامه یک enum که بیانگر انواع مجوزهای برنامه ما است را مشاهده می‌کنید:
namespace SignedXmlSample
{
    public enum LicenseType
    {
        None,
        Trial,
        Standard,
        Personal
    }
}
به همراه کلاسی که اطلاعات مجوز تولیدی را دربر خواهد گرفت:
using System;
using System.Xml.Serialization;

namespace SignedXmlSample
{
    public class License
    {
        [XmlAttribute]
        public Guid Id { set; get; }
        
        public string Domain { set; get; }

        [XmlAttribute]
        public string IssuedTo { set; get; }

        [XmlAttribute]
        public DateTime Expiration { set; get; }

        [XmlAttribute]
        public LicenseType Type { set; get; }
    }
}
خواص این کلاس یا عناصر enum یاد شده کاملا دلخواه هستند و نقشی را در ادامه بحث نخواهند داشت؛ از این جهت که از مباحث XmlSerializer برای تبدیل وهله‌ای از شیء مجوز به معادل XML آن استفاده می‌شود. بنابراین المان‌های آن‌را مطابق نیاز خود می‌توانید تغییر دهید. همچنین ذکر ویژگی XmlAttribute نیز اختیاری است. در اینجا صرفا جهت شبیه سازی معادل مثالی که در ابتدای بحث مطرح شد، از آن استفاده شده است. این ویژگی راهنمایی است برای کلاس XmlSerializer تا خواص مزین شده با آن‌را به شکل یک Attribute در فایل نهایی ثبت کند.


تولید و خواندن مجوز دارای امضای دیجیتال

کدهای کامل کلاس تولید و خواندن یک مجوز دارای امضای دیجیتال را در اینجا مشاهده می‌کنید:
using System;
using System.IO;
using System.Security.Cryptography; // needs a ref. to `System.Security.dll` asm.
using System.Security.Cryptography.Xml;
using System.Text;
using System.Xml;
using System.Xml.Serialization;

namespace SignedXmlSample
{
    public static class LicenseGenerator
    {
        public static string CreateLicense(string licensePrivateKey, License licenseData)
        {
            using (var provider = new RSACryptoServiceProvider())
            {
                provider.FromXmlString(licensePrivateKey);
                var xmlDocument = createXmlDocument(licenseData);
                var xmlDigitalSignature = getXmlDigitalSignature(xmlDocument, provider);
                appendDigitalSignature(xmlDocument, xmlDigitalSignature);
                return xmlDocumentToString(xmlDocument);
            }
        }

        public static string CreateRSAKeyPair(int dwKeySize = 1024)
        {
            using (var provider = new RSACryptoServiceProvider(dwKeySize))
            {
                return provider.ToXmlString(includePrivateParameters: true);
            }
        }

        public static License ReadLicense(string licensePublicKey, string xmlFileContent)
        {
            var doc = new XmlDocument();
            doc.LoadXml(xmlFileContent);

            using (var provider = new RSACryptoServiceProvider())
            {
                provider.FromXmlString(licensePublicKey);

                var nsmgr = new XmlNamespaceManager(doc.NameTable);
                nsmgr.AddNamespace("sig", "http://www.w3.org/2000/09/xmldsig#");

                var xml = new SignedXml(doc);
                var signatureNode = (XmlElement)doc.SelectSingleNode("//sig:Signature", nsmgr);
                if (signatureNode == null)
                    throw new InvalidOperationException("This license file is not signed.");

                xml.LoadXml(signatureNode);
                if (!xml.CheckSignature(provider))
                    throw new InvalidOperationException("This license file is not valid.");

                var ourXml = xml.GetXml();
                if (ourXml.OwnerDocument == null || ourXml.OwnerDocument.DocumentElement == null)
                    throw new InvalidOperationException("This license file is coruppted.");

                using (var reader = new XmlNodeReader(ourXml.OwnerDocument.DocumentElement))
                {
                    var xmlSerializer = new XmlSerializer(typeof(License));
                    return (License)xmlSerializer.Deserialize(reader);
                }
            }
        }

        private static void appendDigitalSignature(XmlDocument xmlDocument, XmlNode xmlDigitalSignature)
        {
            xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(xmlDigitalSignature, true));
        }

        private static XmlDocument createXmlDocument(License licenseData)
        {
            var serializer = new XmlSerializer(licenseData.GetType());
            var sb = new StringBuilder();
            using (var writer = new StringWriter(sb))
            {
                var ns = new XmlSerializerNamespaces(); ns.Add("", "");
                serializer.Serialize(writer, licenseData, ns);
                var doc = new XmlDocument();
                doc.LoadXml(sb.ToString());
                return doc;
            }
        }

        private static XmlElement getXmlDigitalSignature(XmlDocument xmlDocument, AsymmetricAlgorithm key)
        {
            var xml = new SignedXml(xmlDocument) { SigningKey = key };
            var reference = new Reference { Uri = "" };
            reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
            xml.AddReference(reference);
            xml.ComputeSignature();
            return xml.GetXml();
        }

        private static string xmlDocumentToString(XmlDocument xmlDocument)
        {
            using (var ms = new MemoryStream())
            {
                var settings = new XmlWriterSettings { Indent = true, Encoding = Encoding.UTF8 };
                var xmlWriter = XmlWriter.Create(ms, settings);
                xmlDocument.Save(xmlWriter);
                ms.Position = 0;
                return new StreamReader(ms).ReadToEnd();
            }
        }
    }
}
توضیحات:
در حین کار با متد CreateLicense، پارامتر licensePrivateKey همان اطلاعاتی است که به کمک متد CreateRSAKeyPair قابل تولید است. توسط پارامتر licenseData، اطلاعات مجوز در حال تولید اخذ می‌شود. در این متد به کمک provider.FromXmlString، اطلاعات کلیدهای RSA دریافت خواهند شد. سپس توسط متد createXmlDocument، محتوای licenseData دریافتی به یک فایل XML نگاشت می‌گردد (بنابراین اهمیتی ندارد که حتما از ساختار کلاس مجوز یاد شده استفاده کنید). در ادامه متد getXmlDigitalSignature با در اختیار داشتن معادل XML شیء مجوز و کلیدهای لازم، امضای دیجیتال متناظری را تولید می‌کند. با استفاده از متد appendDigitalSignature، این امضاء را به فایل XML اولیه اضافه می‌کنیم. از این امضاء جهت بررسی اعتبار مجوز برنامه در متد ReadLicense استفاده خواهد شد.
برای خواندن یک فایل مجوز امضاء شده در برنامه خود می‌توان از متد ReadLicense استفاده کرد. توسط آرگومان licensePublicKey، اطلاعات کلید عمومی دریافت می‌شود. این کلید دربرنامه، ذخیره و توزیع می‌گردد. پارامتر xmlFileContent معادل محتوای فایل XML مجوزی است که قرار است مورد ارزیابی قرار گیرد.


مثالی در مورد نحوه استفاده از کلاس تولید مجوز

در ادامه نحوه استفاده از متدهای CreateLicense و  ReadLicense را ملاحظه می‌کنید؛ به همراه آشنایی با نمونه کلیدهایی که باید به همراه برنامه منتشر شوند:
using System;
using System.IO;

namespace SignedXmlSample
{
    class Program
    {
        static void Main(string[] args)
        {
            //Console.WriteLine(LicenseGenerator.CreateRSAKeyPair());
            writeLicense();            
            readLicense();

            Console.WriteLine("Press a key...");
            Console.ReadKey();
        }

        private static void readLicense()
        {
            var xml = File.ReadAllText("License.xml");
            const string publicKey = @"<RSAKeyValue>
                                    <Modulus>
                                        mBNKFIc/LkMfaXvLlB/+6EujPkx3vBOvLu8jdESDSQLisT8K96RaDMD1ORmdw2XNdMw/6ZBuJjLhoY13qCU9t7biuL3SIxr858oJ1RLM4PKhA/wVDcYnJXmAUuOyxP/vfvb798o6zAC1R2QWuzG+yJQR7bFmbKH0tXF/NOcSgbc=
                                    </Modulus>
                                    <Exponent>
                                        AQAB
                                    </Exponent>
                                 </RSAKeyValue>";

            var result = LicenseGenerator.ReadLicense(publicKey, xml);

            Console.WriteLine(result.Domain);
            Console.WriteLine(result.IssuedTo);
        }

        private static void writeLicense()
        {
            const string rsaData = @"<RSAKeyValue>
                    <Modulus>
                        mBNKFIc/LkMfaXvLlB/+6EujPkx3vBOvLu8jdESDSQLisT8K96RaDMD1ORmdw2XNdMw/6ZBuJjLhoY13qCU9t7biuL3SIxr858oJ1RLM4PKhA/wVDcYnJXmAUuOyxP/vfvb798o6zAC1R2QWuzG+yJQR7bFmbKH0tXF/NOcSgbc=
                    </Modulus>
                    <Exponent>
                        AQAB
                    </Exponent>
                    <P>
                        xwPKN77EcolMTD2O2Csv6k9Y4aen8UBVYjeQ4PtrNGz0Zx6I1MxLEFzRpiKC/Ney3xKg0Icwj0ebAQ04d5+HAQ==
                    </P>
                    <Q>
                        w568t0Xe6OBUfCyAuo7tTv4eLgczHntVLpjjcxdUksdVw7NJtlnOLApJVJ+U6/85Z7Ji+eVhuN91yn04pQkAtw==
                    </Q>
                    <DP>
                        svkEjRdA4WP5uoKNiHdmMshCvUQh8wKRBq/D2aAgq9fj/yxlj0FdrAxc+ZQFyk5MbPH6ry00jVWu3sY95s4PAQ==
                    </DP>
                    <DQ>
                        WcRsIUYk5oSbAGiDohiYeZlPTBvtr101V669IUFhhAGJL8cEWnOXksodoIGimzGBrD5GARrr3yRcL1GLPuCEvQ==
                    </DQ>
                    <InverseQ>
                        wIbuKBZSCioG6MHdT1jxlv6U1+Y3TX9sHED9PqGzWWpVGA+xFJmQUxoFf/SvHzwbBlXnG0DLqUvxEv+BkEid2w==
                    </InverseQ>
                    <D>                        Yk21yWdT1BfXqlw30NyN7qNWNuM/Uvh2eaRkCrhvFTckSucxs7st6qig2/RPIwwfr6yIc/bE/TRO3huQicTpC2W3aXsBI9822OOX4BdWCec2txXpSkbZW24moXu+OSHfAdYoOEN6ocR7tAGykIqENshRO7HvONJsOE5+1kF2GAE=
                    </D>
                  </RSAKeyValue>";

            string data = LicenseGenerator.CreateLicense(
                                                rsaData,
                                                new License
                                                {
                                                     Id = Guid.NewGuid(),
                                                     Domain = "dotnettips.info",
                                                     Expiration = DateTime.Now.AddYears(2),
                                                     IssuedTo = "VahidN",
                                                     Type = LicenseType.Standard
                                                });
            File.WriteAllText("License.xml", data);
        }
    }
}
ابتدا توسط متد CreateRSAKeyPair کلیدهای لازم را تهیه و ذخیره کنید. این کار یکبار باید صورت گیرد.
همانطور که مشاهده می‌کنید، اطلاعات کامل یک نمونه از آن، در متد writeLicense مورد نیاز است. اما در متد readLicense تنها به قسمت عمومی آن یعنی Modulus و Exponent نیاز خواهد بود (موارد قابل انتشار به همراه برنامه).

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

دریافت نسخه جنریک این مثال:
SignedXmlSample.zip
مطالب
ASP.NET MVC #4

بررسی نحوه ارتباطات بین اجزای مختلف الگوی MVC در ASP.NET MVC

اینبار برخلاف قسمت قبل، قالب پروژه خالی ASP.NET MVC را در VS.NET انتخاب کرده (ASP.NET MVC 3 Web Application و بعد انتخاب قالب Empty نمایش داده شده) و سپس پروژه جدیدی را شروع می‌کنیم. View Engine را هم Razor در نظر خواهیم گرفت.
پس از ایجاد ساختار اولیه پروژه، بدون اعمال هیچ تغییری، برنامه را اجرا کنید. بلافاصله با پیغام The resource cannot be found یا 404 یافت نشد، مواجه خواهیم شد.
همانطور که در پایان قسمت دوم نیز ذکر شد، پردازش‌ها در ASP.NET MVC از کنترلرها شروع می‌شوند و نه از صفحات وب. بنابراین برای رفع این مشکل نیاز است تا یک کلاس کنترلر جدید را اضافه کنیم. به همین جهت بر روی پوشه استاندارد Controllers کلیک راست کرده، از منوی ظاهر شده قسمت Add، گزینه‌ی Controller را انتخاب کنید:


در صفحه بعدی که ظاهر می‌شود، نام HomeController را وارد کنید (با توجه به اینکه مطابق قراردادهای ASP.NET MVC، نام کنترلر باید به کلمه Controller ختم شود). البته لازم به ذکر است که این مراحل را به همان شکل متداول مراجعه به منوی Project و انتخاب Add Class و سپس ارث بری از کلاس Controller نیز می‌توان انجام داد و طی این مراحل الزامی نیست. کلاسی که به صورت خودکار از طریق منوی Add Controller یاد شده ایجاد می‌شود، به شکل زیر است:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
//
// GET: /Home/
public ActionResult Index()
{
return View();
}
}
}

سؤال:
در قسمت دوم عنوان شد که کنترلر باید کلاسی باشد که اینترفیس IController را پیاده سازی کرده است، اما در اینجا ارث بری از کلاس Controller را شاهد هستیم. جریان چیست؟!
سلسله مراتبی که بکارگرفته شده به صورت زیر است:
public abstract class ControllerBase : IController
public abstract class Controller : ControllerBase

ControllerBase، اینترفیس IController را پیاده سازی کرده و سپس کلاس Controller از کلاس ControllerBase مشتق شده است. شاید بپرسید که این همه پیچ و تاب برای چیست؟!
مشکلی که با اینترفیس خالص وجود دارد، عدم نگارش پذیری آن است. به این معنا که اگر متدی یا خاصیتی در نگارش بعدی به این اینترفیس اضافه شد، هیچکدام از پروژه‌های قدیمی دیگر کامپایل نخواهند شد و باید ابتدا این متد یا خاصیت جدید را نیز لحاظ کنند. اینجا است که کار کلاس‌های abstract شروع می‌شود. در یک کلاس abstract می‌توان پیاده سازی پیش فرضی را نیز ارائه داد. به این ترتیب مصرف کننده نهایی کلاس Controller متوجه این تغییرات نخواهد شد.
اگر برنامه نویس «من» باشم، شما رو وادار خواهم کرد که متدهای جدید اینترفیس تعریفی‌ام را پیاده سازی کنید! همینه که هست! اما اگر طراح مایکروسافت باشد، بلافاصله انبوهی از جماعت ایرادگیر که بالای 100 تا از کنترلر‌های اون‌ها الان فقط در یک پروژه از کار افتاده،‌ ممکن است جلوی دفتر مایکروسافت دست به خود سوزی بزنند! اینجا است که مایکروسافت مجبور است تا این پیچ و تاب‌ها را اعمال کند که اگر روزی متدی در اینترفیس IController بنابر نیازهای جدید درنظر گرفته شد، بتوان سریع یک پیاده سازی پیش فرض از آن‌را در کلاس‌های abstract یاد شده قرار داد (یکی از تفاوت‌های مهم کلاس‌های abstract با اینترفیس‌ها) تا جماعت ایرادگیر و نق‌زن متوجه تغییری نشوند و باز هم پروژه‌های قدیمی بدون مشکل کامپایل شوند. تابحال به فلسفه وجودی کلاس‌های abstract از این دیدگاه فکر کرده بودید؟!

بعد از این توضیحات و کارها، اگر اینبار برنامه را اجرا کنیم، خطای زیر نمایش داده می‌شود:

The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Home/Index.aspx
~/Views/Home/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/Home/Index.cshtml
~/Views/Home/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml

همانطور که ملاحظه می‌کنید چون نام کنترلر ما Home است، فریم ورک در پوشه استاندارد Views در زیر پوشه‌ای به همان نام Home، به دنبال یک سری فایل می‌گردد. فایل‌های aspx مربوط به View Engine ایی به همین نام بوده و فایل‌های cshtml و vbhtml مربوط به View Engine دیگری به نام Razor هستند.
بنابراین نیاز است تا یکی از این فایل‌ها را در مکان‌های یاد شده ایجاد کنیم. برای این منظور حداقل دو راه وجود دارد. یا دستی اینکار را انجام دهیم یا اینکه از ابزار توکار خود VS.NET برای ایجاد یک View جدید استفاده کنیم.
برای ایجاد View ایی مرتبط با متد Index (در ASP.NET MVC نام دیگر متدهای قرار گرفته در یک کنترلر، Action نیز می‌باشد)، روی خود متد کلیک راست کرده و گزینه Add View را انتخاب کنید:


در صفحه بعدی ظاهر شده، پیش فرض‌ها را پذیرفته و بر روی دکمه Add کلیک نمائید. اتفاقی که رخ خواهد داد شامل ایجاد فایل Index.cshtml، با محتوای زیر است (با توجه به اینکه زبان پروژه سی شارپ است و View Engine انتخابی Razor می‌باشد، cshtml تولید گردید و گرنه vbhtml ایجاد می‌شد):

@{
ViewBag.Title = "Index";
}
<h2>Index</h2>

مجددا برنامه را اجرا کنید. اینبار بدون خطایی کلمه Index را در صفحه تولیدی می‌توان مشاهده کرد. نکته جالب این فایل‌های View جدید، عدم مشاهده ویژگی‌های runat=server و سایر موارد مشابه است.

چند سؤال مهم:
در حین ایجاد اولین کنترلر جهت نمایش صفحه پیش فرض برنامه، نام HomeController انتخاب شد. چرا مثلا نام TestController وارد نشد؟ برنامه از کجا متوجه شد که باید حتما این کنترلر را پردازش کند. نقش متد Index چیست؟ آیا حتما باید Index باشد و در اینجا نام دیگری را نمی‌توان وارد کرد؟ «قرارداد» پردازشی این‌ها کجا تنظیم می‌شود؟ فریم ورک، این سیم کشی‌ها را چگونه انجام می‌دهد؟
پاسخ به تمام این سؤال‌ها، در ویژگی «مسیریابی یا Routing» نهفته است. فایل Global.asax.cs برنامه را باز کنید. تعاریف مرتبط با مسیریابی پیش فرض را در متد RegisterRoutes آن می‌توان مشاهده کرد:

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}



پروسه هدایت یک درخواست HTTP به یک کنترلر، در اینجا مسیریابی یا Routing نامیده می‌شود. این قابلیت در فضای نام System.Web.Routing تعریف شده است و باید دقت داشت که جزو ASP.NET MVC نیست. این امکانات جزو ASP.NET Runtime است و به همراه دات نت 3.5 سرویس پک یک برای اولین بار ارائه شد. بنابراین جهت استفاده در ASP.NET Web forms نیز مهیا است. در ASP.NET MVC از این امکانات برای ارسال درخواست‌ها به کنترلرها استفاده می‌شود.
در متد routes.MapRoute فراخوانی شده‌ای که در کدهای بالا ملاحظه می‌کنید، کار نگاشت یک URL به Actionهای یک کنترلر صورت می‌گیرد (یا همان متدهای تعریف شده در کنترلرها). همچنین از این URLها پارامترهای این متدها یا اکشن‌ها نیز قابل استخراج است.
در متد MapRoute، اولین پارامتر تعریف شده، یک نام پیش فرض است و در ادامه اگر آدرسی را به فرم «یک چیزی اسلش یک چیزی اسلش یک چیزی» یافت، اولین قسمت آن‌را به عنوان نام کنترلر تفسیر خواهد کرد، دومین قسمت آن، نام متد عمومی موجود در کنترلر فرض شده و سومین قسمت به عنوان پارامتر ارسالی به این متد پردازش می‌شود.
برای مثال از آدرس زیر اینطور می‌توان دریافت که:
http://hostname/home/about

Home نام کنترلی است که فریم ورک به دنبال آن خواهد گشت تا این درخواست رسیده را پردازش کند و about نام متدی عمومی در این کلاس است که به صورت خودکار فراخوانی می‌گردد. در اینجا پارامتر id ایی هم وجود ندارد. در یک برنامه امکان تعریف چندین و چند مسیریابی وجود دارد.
پارامتر سوم متد routes.MapRoute، یک سری پیش فرض را تعریف می‌کند و این مورد همانجایی است که از اطلاعات آن جهت تعریف کنترلر پیش فرض استفاده کردیم. برای مثال به چهار آدرس زیر دقت نمائید:

http://localhost/
http://localhost/home
http://localhost/home/about
http://localhost/process/list

در حالت http://localhost/،‌ هر سه مقدار پیش فرض مورد استفاده قرار خواهند گرفت چون سه جزئی ({controller}/{action}/{id}) که موتور مسیریابی به دنبال آن‌ها می‌گردد، در این آدرس وجود خارجی ندارد. بنابراین نام کنترلر پیش فرض در این حالت همان Home مشخص شده در پارامتر سوم متد routes.MapRoute خواهد بود و متد پیش فرض نیز Index و پارامتری هم به آن ارسال نخواهد شد.
در حالت http://localhost/home نام کنترلر مشخص است اما دو جزء دیگر ذکر نشده‌اند، بنابراین مقادیر آن‌ها از پیش فرض‌های صریح ذکر شده در متد routes.MapRoute گرفته می‌شود. یعنی نام متد اکشن مورد پردازش، Index خواهد بود به همراه هیچ آرگومان خاصی.
به علاوه باید خاطرنشان کرد که این مقادیر case sensitive یا حساس به بزرگی و کوچکی حروف نیستند. بنابراین مهم نیست که http://localhost/HoMe باشد یا http://localhost/HOMe یا هر ترکیب دیگری.
یا اگر آدرس رسیده http://localhost/process/list باشد، این مسیریابی پیش فرض تعریف شده قادر به پردازش آن می‌باشد. به این معنا که کنترلری به نام Process وهله سازی و سپس متدی به نام List در آن فراخوانی خواهند شد.

یک نکته:
ترتیب routes.MapRouteهای تعریف شده در اینجا مهم است و اگر اولین URL رسیده با الگوی تعریف شده مطابقت داشت، کار را تمام خواهد کرد و به سایر تعاریف نخواهد رسید. مثلا اگر در اینجا یک مسیریابی دیگر را به نام Process تعریف کنیم:

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
"Process", // Route name
"Process/{action}/{id}", // URL with parameters
new { controller = "Process", action = "List", id = UrlParameter.Optional } // Parameter defaults
);

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}

آدرسی به فرم http://localhost/Process، به صورت خودکار به کنترلر Process و متد عمومی List آن نگاشت خواهد شد و کار به مسیریابی بعدی نخواهد رسید.


مطالب
آشنایی با NuGet - قسمت اول

NuGet چیست؟

روش متداول استفاده از کتابخانه‌های موجود دات نتی در Visual studio‌ عموما به این صورت است: مراجعه به سایت مربوطه، دریافت بسته مورد نظر، باز کردن آن و سپس افزودن ارجاعی به اسمبلی‌های آن کتابخانه. در این حالت زمانیکه نسخه‌ی جدیدی از کتابخانه‌ی مورد استفاده ارائه ‌شود (و عموما تا مدت‌ها شاید از آن بی‌اطلاع باشیم) تمام این مراحل باید از ابتدا تکرار شوند و همینطور الی آخر.
برای رفع این نقیصه، تیم ASP.NET، افزونه‌ای سورس باز و رایگان را به نام NuGet جهت VS.Net 2010 طراحی کرده‌اند که کار مدیریت بسته‌های کتابخانه‌های مورد استفاده را بسیار ساده کرده است. امکانات این افزونه پس از نصب، در دو حالت استفاده از رابط گرافیکی کاربری آن و یا با استفاده از خط فرمان PowerShell ویندوز در دسترس خواهد بود. این افزونه در زمان بارگذاری، با مراجعه به فید سایت مرکزی خود، لیست بسته‌های مهیا را در اختیار علاقمندان قرار می‌دهد. درب این سایت مرکزی به روی تمام توسعه‌ دهنده‌ها جهت افزودن بسته‌های خود باز است.
و ... فراگیری کار با NuGet برای تمام برنامه نویسان دات نت لازم و ضروری است! از این جهت که پیغام "این بسته تنها برای NuGet عرضه شده است" کم کم در حال متداول شدن می‌باشد و دیگر سایت‌های مرتبط، لینک مستقیمی را جهت دریافت کتابخانه‌های خود ارائه نمی‌دهند. حتی خبر به روز شدن محصولات خود را هم شاید دیگر به صورت منظم ارائه ندهند؛ زیرا NuGet کار مدیریت آن‌ها را به عهده خواهد داشت.


دریافت و نصب NuGet

NuGet را حداقل به سه طریق می‌توان دریافت و نصب کرد:
الف) با مراجعه به سایت CodePlex : (+)
ب) دریافت آن از سایت گالری‌های آن : (+)


ج) با استفاده از امکانات VS.NET

هر سه روش فوق به دریافت و نصب فایل NuGet.Tools.vsix منتهی می‌شوند. برای مثال در روش (ج) باید به منوی Tools و گزینه‌ی Extension Manager مراجعه کنید. سپس برگه‌ی Online Gallery را گشوده و اندکی صبر کنید تا اطلاعات آن دریافت و نمایش داده شود. سپس NuGet را در Search box بالای صفحه نوشته و NuGet Package manager ظاهر شده را انتخاب و نصب کنید.



نحوه استفاده از NuGet

فرض کنید یک پروژه جدید ASP.NET را ایجاد کرده‌اید و نیاز است تا کتابخانه‌ی ELMAH به آن اضافه شود. روش انجام اینکار را به کمک NuGet در ادامه بررسی خواهیم کرد (کمتر از یک دقیقه زمان خواهد برد):

الف) با کمک امکانات رابط گرافیکی کاربر آن
ساده‌ترین روش استفاده از NuGet ، کلیک راست بر روی پوشه References در Solution explorer و سپس انتخاب گزینه‌ی Add Library Package Reference می‌باشد:



در صفحه‌ی باز شده، برگه‌ی Online را باز کنید و مدتی صبر نمائید تا اطلاعات لازم دریافت گردد (در زمان نگارش این مطلب، 1135 بسته در این مخزن موجود است):



سپس در جعبه‌ی جستجوی سمت راست بالای صفحه، نام کتابخانه‌ی مورد نظر را نوشته و اندکی صبر کنید تا اطلاعات آن نمایش داده شود:



اکنون با کلیک بر روی دکمه Install ، بسته مرتبط با این کتابخانه دریافت شده و سپس به صورت خودکار ارجاعی به آن نیز افزوده خواهد شد. همچنین تنظیمات مرتبط با فایل Config برنامه هم اضافه می‌شوند.

روش دیگر ظاهر کردن این صفحه، مراجعه به منوی Tools و گزینه‌ی Library Package Manager می‌باشد:



جهت دریافت به روز رسانی‌های بسته‌های نصب شده تنها کافی است به برگه‌ی Updates این صفحه مراجعه کرده و موارد لیست شده را نصب نمائیم:



نکته: NuGet در SharpDevelop 4.1 به بعد هم پشتیبانی می‌شود:




ب) با استفاده از امکانات خط فرمان PowerShell ویندوز
برای استفاده از امکانات پاورشل ویندوز نیاز است تا پاورشل نگارش 2 بر روی سیستم شما نصب باشد (نیاز به Windows XP with Service Pack 3 به بعد دارد). سپس به منوی Tools ، قسمت Library Package Manager ، گزینه‌ی Package Manager Console آن جهت فعال سازی کنسول پاور شل در VS.NET مراجعه نمائید:


نکته: در تصویر فوق پس از نوشتن el ، دکمه tab فشرده شده است. در این حالت منوی پکیج‌های مهیای شروع شده با el، از سایت مرکزی NuGet ظاهر گردیده است.

فرامین مهمی که در اینجا در دسترس هستند شامل: List-Package ، Uninstall-Package ، Update-Package و Get-Package می‌باشند. برای مثال اگر قصد جستجو در بین بسته‌های موجود را داشته باشید Get-Package بسیار مفید است:



برای مثال جهت یافتن بسته‌های مرتبط با wpf و silverlight به صورت زیر می‌توان عمل کرد:
PM> get-package -remote -filter wpf
PM> get-package -remote -filter silverlight

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


ج) استفاده از برنامه NuGet.exe
برنامه NuGet.exe از سایت CodePlex قابل دریافت است. این روش هم جهت علاقمندان به خط فرمان تدارک دیده شده است!
پس از دریافت آن فرض کنید می‌خواهیم تمام بسته‌های شروع شده با nhi را لیست کنیم. برای این منظور دستور خط فرمان ذیل را صادر کنید:
D:\Test>nuget list nhi
سپس برای دریافت مثلا NHibernate تنها کافی است دستور زیر اجرا شود:
D:\Test>nuget install NHibernate

به این صورت کتابخانه NHibernate ‌به همراه تمام وابستگی‌های آن دریافت خواهد شد.

به روز رسانی خودکار NuGet
برای به روز رسانی برنامه nuget.exe دستور زیر را می‌توان صادر نمود:
D:\Test>NuGet.exe u
و یا جهت فعال سازی به روز رسانی‌های خودکار افزونه‌ها در VS.NET به منوی زیر مراجعه کنید:
Tools | Options, then Environment | Extension Manager and click "Automatically check for updates to installed extensions."





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

مطالب
Senior Developer به چه کسی گفته می شود؟
چند وقت پیش با یک آگهی استخدام برنامه نویس به صورت زیر برخورد کردم:
      Senior Developer
      .Net Technologies
      Resume : ------------------------------------
آگهی بالا خلاصه‌ترین آگهی استخدامیه که می‌تونید ببنید و البته بیشتر هم در رشته کامپیوتر و مخصوصا جامعه برنامه نویسان رواج دارد.
احتمالا اکثر شما هم در آگهی‌های استخدام برنامه نویس، با واژه Senior Developer یا برنامه نویس ارشد برخورد داشته اید. حال به راستی به چه کسی برنامه نویس ارشد گفته می‌شود. یا بهتره بگم که چه زمانی ما می‌تونیم خودمون را یک برنامه نویس ارشد بدونیم؟
از آنجا که تعریف مشخصی برای این واژه‌ها در فرهنگ خاصی وجود ندارد و عموما هر کسی یک تعریف خاص با توجه به سلیقه خودش در این زمینه ارائه می‌دهد نمی‌توان یک شرح واحد از این واژه‌ها نظیر Senior Developer یا حتی Junior Developer ارائه داد. در نتیجه قصد دارم با توجه به تجربیات شخصی، این موارد رو تشریح کنم.
در خیلی موارد منظور از برنامه نویس ارشد، کسی است که:
  • در حداقل یک یا دو زبان برنامه نویسی تجربه داشته باشد؛
  • با تکنولوژی‌های مهم و کارآمد ارائه شده در آن زبان آشنایی کامل داشته باشد؛
  • توانایی استفاده از این تکنولوژی‌ها را در جای مناسب پروژه دارا باشد؛
  • با الگوهای برنامه نویسی (Design Pattern) آشنایی کامل داشته باشد؛
  • بتواند به سایر اعضای تیم در حل مشکلات و باگ‌های برنامه کمک کند؛
  • یک خطایاب قهار باشد(منظور این است با اکثر استثنائات و خطاهای متداول زبان و تکنولوژی که پروژه با آن پیاده سازی می‌شود آشنا باشد و بداند که چه زمان این خطا به وجود می‌آید و چگونه می‌توان این موارد را برطرف کرد)؛
  • باید با پیاده سازی سیستم‌های سرویس گرا (SOA) جدای از تکنولوژی پیاده سازی آن آشنایی کامل داشته باشد؛
  • باید با روش‌های تست و خطایابی و ابزار‌های توسعه و پیاده سازی آن آشنا بوده و توانایی استفاده از آن‌ها را در پروژه‌های خود داشته باشد؛
  • یک برنامه نویس ارشد باید در زمینه تخمین زمان تکمیل پروژه مهارت داشته باشد. باید بتواند مدت زمان لازم برای تکمیل یک Task را تخمین بزند و در همین مدت زمان، Task مربوطه را به صورت کامل پیاده سازی نماید.
  • در خیلی موارد باید بتواند هماهنگی لازم را بین اعضای تیم برنامه نویسی ایجاد نماید؛
  • و...

*ترتیب عبارات بالا دلیلی بر اولویت موارد ذکر شده نیست.

*منظور از آشنایی در عبارات بالا، یعنی تسلط و توانایی استفاده از آن با آگاهی تمام.

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

برای به دست آوردن مهارت‌ها و توانایی‌های یک برنامه نویس ارشد لازم است که حداقل 8 تا 10 سال تجربه برنامه نویسی در یک زبان را داشته باشید. البته این در مورد همگان صادق نیست . شاید کسی بتواند این راه  را در کمتر از 8 سال طی نماید. این بستگی به تلاش و استعداد فرد دارد. اما تجربه بیشتر یعنی شرکت در پروژه‌های بیشتر و آمادگی بیشتر در حل مشکلات و مسائل مختلف در طی روند تکمیل پروژه. برای مثال در زمینه تخمین اجرای یک Task داشتن تجربه بیشتر خیلی به شما کمک خواهد کرد.

در پایان چهار ردیف یا رده مختلف را که بین برنامه نویسان رواج دارد ذکر می‌کنم.(از پایین به بالا)

Junior : عموما به کسی گفته می‌شود که 1 تا 3 سال تجربه برنامه نویسی دارد. معمولا کد‌های نوشته شده توسط این افراد باید بررسی شود چون احتمال اشتباه در آن زیاد است. اکثر کد‌های نوشته شده توسط این افراد به صورت dirty code است. راهنمایی هایی که به این افراد داده می‌شود شامل راهنمایی در زمینه ساختاری و الگوریتمی نیز می‌باشد. 

Mid-Level : برنامه نویسان در این رده بین 4 تا 6 سال تجربه دارند. می‌توانند به تنهایی نیز یک مشکل موجود در پروژه را حل نمایند. با مباحث مربوطه به طراحی کامپوننت آشنایی دارند و پروژه را بی نیاز از کامپوننت خواهند کرد. حتی در بعضی موارد می‌توانند به تنهایی یک پروژه در سطح کوچک با متوسط را توسعه دهند. 

Senior Developer : در بالا به صورت کامل شرح داده شد.

Luminary : به صورت معمول به کسی گفته می‌شود که تمام توانایی‌های یک برنامه نویس ارشد را داراست و فقط تجربه برنامه نویسی آن قطعا از 10 سال بیشتر است.

از این واژه کمتر در رده‌های برنامه نویسی استفاده می‌شود و بیشتر به همان واژه Senior Developer بسنده می‌کنند.