مطالب
اشیاء context در ASP.NET
در asp.net  تعدادی اشیاء پایه، حاوی اطلاعات بسیار با ارزشی در خصوص درخواست جاری، application و پاسخی که ارسال می‌شود هستند و به صورت غیر مستقیم جهت دست‌یابی به قسمتهای مرکزی و هسته‌ای چهارچوب asp.net مانند security , stat data می‌توان این اشیاء را بکار گرفت.
بررسی این اشیاء از این جهت حائز اهمیت است که در کنترلر‌ها و ویوها می‌توان پاسخهای ارسالی به کلاینت‌ها را بر حسب شرایط مختلفی مانند درخواست رسیده یا حالت خاص دیگری تغییر داد. ضمن اینکه از این اشیاء در ماژول‌ها و هندلر‌ها نیز استفاده می‌شود. لذا قبل از پرداختن به مفاهیم مرتبط به ماژولها و هندلرها بهتر است این اشیاء بررسی شوند.

کلاس httpcontext هسته‌ی چهارچوب Asp.net است که خواص بسیار مهمی به شرح ذیل را فراهم می‌آورد:
Application : شیء HttpAplicationState را جهت مدیریت Application State Data بر می‌گرداند.
ApplicationInstance  : شیء HttpApplication مرتبط با درخواست جاری را بر می‌گرداند.
Cache : شیء Cache را جهت کش داده‌ها بر می‌گرداند.
Current : خصوصیت استاتیکی که شیء HttpContext درخواست جاری را بر می‌گرداند.
CurrentHandler : وهله‌ای از IHttpHandler را که محتویات درخواست جاری را تولید خواهد کرد،  بر می‌گرداند.
IsDebuggingEnabled : مقدار True یا False را بسته به اینکه Debug فعال باشد یا خیر بر می‌گرداند.
Items : یک Collection را که می‌تواند جهت انتقال State Data بین اجزاء مختلف فریم ورک که در پردازش یک درخواست همکاری می‌کنند، بر گرداند.
GetSection : قسمت خاصی از فایل Web.Config را بر می‌گرداند.
Request : شیء HttpRequest را که حاوی جزئیات درخواست پردازش شده است، بر می‌گرداند.
Response : شیء HttpResponse را بر می‌گرداند که حاوی جزئیات Response ای است که آماده ارسال به مرورگر است.
Session : برگرداننده‌ی شیء HttpSession است. این خاصیت قبل از وقوع رخداد PostAcquireRequestState مربوط به Application، مقدار null را خواهد داشت.
TimeStamp : شیء از نوع Datetime و معرف زمانی است که شیء HttpContext ایجاد شده‌است.
Trace : جهت ثبت اطلاعات تشخیصی به کار می‌رود.

در فایل global از طریق خاصیت Context به وهله‌ای از HttpContext دسترسی داریم. ولی این خاصیت فراگیر نبوده و در ویوها و کنترلر‌ها از طریق خاصیت HttpContext  در دسترس است که در کنترلر خاصیتی از کلاس پایه Controller و در ویو خاصیتی از کلاس پایه WebViewPage می‌باشد و در ماژول‌ها از طریق پارامتر ورودی متد Init در دسترس است‌.
در هندلر‌ها متد ProcessRequest وهله‌ای از شیء HttpContext را دریافت می‌کند.
به طور سراسری در هر نقطه‌ای از برنامه از طریق خاصیت استاتیک HttpContext.Current  به شیء HttpContext مرتبط با درخواست جاری دسترسی خواهیم داشت.
در کلاسهای مدل نیز از طریق خاصیت استاتیک یاد شده می‌توان به این شیء دسترسی داشت؛ ولی بهتر است اگر مدل نیاز به اطلاعاتی در خصوص یک Request داشت این اطلاعات از طریق اشیاء Context در کنترلر دریافت و به عنوان آرگومان به مدل ارسال شوند.
به صورت کلی، خلاصه‌ی مطالب فوق به صورت ذیل می‌باشد:

بخش مورد نظر 
روش دسترسی به اشیاء context
 Controller 
 از طریق خاصیت HttpContext
View 
خاصیت Context
Global Application Class خاصیت Context
Modules 
آرگومان متد Init
Handlers 
 آرگومان متد ProcessRequest
به صورت کلی از طریق خاصیت استاتیک HttpContext.Current


خواص ذکر شده‌ی در جدول فوق، همگی نوع یکسانی ندارند. در فایل  global و هندلر‌ها و ماژولها، دقیقا به همان HtpContext ای دسترسی داریم که قبلا با آن‌ها آشنا شدیم. این نوع از اشیاء (منظور خواص کلاس HttpContext) قبل از اینکه فریم ورک MVC، دست به کار مدیریت یک درخواست شود، کار خود را شروع می‌کنند که این امر کار آزمایش واحد را مشکل می‌کند. برای رفع این مشکل خواص مهیا در کنترلر و ویو وهله‌هایی از کلاسهای متفاوتی را برمی گردانند که از کلاس Context مشتق شده‌اند و ضمنا آزمایش واحد را به سادگی پشتیبانی می‌کنند(+ ) . خاصیت HttpContext کلاس Controller وهله‌ای از کلاس HttpContextBase را بر می‌گردانند. همه‌ی اشیاء context موجود در این کلاس، دارای پسوند Base هستند؛ مانند : HttpRequestBase, HttpResponseBase و...
اگر نیاز داشتید که یک شیء از نوع پسوند دار Base را از یک شیء فاقد این پسوند ایجاد کنید، برای مثال یک شیء HttpRequest دارید، ولی متدی دارید که آرگومان آن وهله‌ای از کلاس HttpRequestBase است، برای این کار کلاسهایی با پسوند Wrapper مانند HttpContextWrapper ,…  وجود دارند که از کلاسهایی با پسوند Base مشتق شده و در متد سازنده خود آرگومانی از کلاسهای اصلی فاقد پسوند Base را می‌گیرند.
ولی عکس آن امکان پذیر نیست و نمی‌توان کلاس با پسوند Base را به نوع اولیه برگرداند. ولی همان طور که گفتیم هر جایی که نیاز داشتیم، می‌توان از طریق خاصیت استاتیک System.Web.HTTPContext.Current به اشیاء Context اصلی دسترسی داشت.
بسیاری از کلاسهای فریم ورک Asp.Net دارای خاصیت‌هایی هستند که به خوااص کلاس HttpContext نگاشت شده‌اند. یکی از این نمونه‌ها کلاس HttpApplication است که کلاس پایه‌ی فایل global نیز هست. همان طور که در ذیل نیز می‌بینید، بسیاری از خواص و متدهای کلاس HttpApplication به نوعی مرتبط با اشیاء context هستند.

Application : به خاصیت HttpContext.Application نگاشت شده‌است که دسترسی به state data application را مهیا می‌سازد.
CompleteRequest : به چرخه حیات جاری خاتمه خاتمه داده و آن را مستقیما به رخداد LogRequest منتقل می‌کند.
Context : شیء HttpContext مرتبط با درخواست جاری را بر می‌گرداند.
Init : هر گاه متد Init یکی از ماژولهای ثبت شده در برنامه فراخوانی شود، این متد صدا زده خواهد شد.
Modules : یک شیء HttpModuleCollection را که حاوی جزئیات ماژولهای برنامه است، بر می‌گرداند.
RegisterModule(type: متد استاتیکی است که یک ماژول جدید را ثبت می‌کند.
Request : مقدار HttpContext.Request را برگشت می‌دهد و در صورتی که این مقدار null باشد، استثنایی رخ خواهد داد.
Response : مقدار HttpContext.Response را برگشت داده و در صورت null بودن این مقدار، استثنایی رخ می‌دهد.
Server : به خاصیت HttpContext.Server نگاشت شده است.
Session : مقدار HttpContext.Session را برگشت می‌دهد که در صورت null بودن این مقدار، استثنایی رخ خواهد داد.

در این مقاله با خواص کلاس HttpContext که اشیائی مهم و پرکاربرد بوده و حاوی اطلاعات بسیار سودمندی هستند، آشنا شدیم. ضمنا همان طور که در ابتدای مقاله گفته شد، از این اشیاء در ماژول‌ها و هندلرها استفاده‌ی زیادی می‌شود.
مطالب
یک دست سازی ی و ک در برنامه‌های Entity framework 6
تا قبل از EF 6 برای طراحی یک سیستم عمومی تغییر مقادیر ثبت شده در بانک اطلاعاتی، می‌شد با استفاده از امکانات توکار Tracking آن، مقادیر تغییر کرده را یافت و برای مثال ی و ک آن‌ها را پیش از درج در بانک اطلاعاتی، یک دست کرد. در EF 6 با معرفی یک سری interceptor می‌توان به مراحل پیش و پس از اجرای کوئری‌ها دسترسی پیدا کرد. عمده‌ترین کاربرد آن، لاگ کردن SQLهای تولیدی و نوشتن برنامه‌هایی شبیه به EF Profiler است. اما ... استفاده‌ی دیگری را نیز می‌توان از IDbCommandInterceptor جدید آن تدارک دید: دستکاری SQL تولیدی توسط آن پیش از اعمال به بانک اطلاعاتی.

طراحی یک Interceptor برای یک دست سازی ی و ک

در اینجا کدهای کلاس YeKeInterceptor را ملاحظه می‌کنید. در متدهایی که به کلمه‌ی Executing ختم می‌شوند، می‌توان به دستورات SQL تولید شده توسط EF، پیش از اعمال بر روی بانک اطلاعاتی دسترسی داشت:
    public class YeKeInterceptor : IDbCommandInterceptor
    {
        public void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
        {
            command.ApplyCorrectYeKe();
        }

        public void NonQueryExecuted(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
        {
        }

        public void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
        {
            command.ApplyCorrectYeKe();
        }

        public void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
        {
        }

        public void ScalarExecuted(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
        {
        }

        public void ScalarExecuting(DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
        {
            command.ApplyCorrectYeKe();
        }
    }
DbCommand، حاوی تمام اطلاعاتی است که به آن نیاز داریم؛ شامل CommandText یا همان SQL تولید شده و همچنین command.Parameters برای دسترسی به مقادیر پارامترهای کوئری. نکته‌ی مهم تمام این موارد، قابل ویرایش بودن آن‌ها است.
    public static class YeKe
    {
        public const char ArabicYeChar = (char)1610;
        public const char PersianYeChar = (char)1740;

        public const char ArabicKeChar = (char)1603;
        public const char PersianKeChar = (char)1705;

        public static string ApplyCorrectYeKe(this object data)
        {
            return data == null ? null : ApplyCorrectYeKe(data.ToString());
        }

        public static string ApplyCorrectYeKe(this string data)
        {
            return string.IsNullOrWhiteSpace(data) ?
                        string.Empty :
                        data.Replace(ArabicYeChar, PersianYeChar).Replace(ArabicKeChar, PersianKeChar).Trim();
        }

        public static void ApplyCorrectYeKe(this DbCommand command)
        {
            command.CommandText = command.CommandText.ApplyCorrectYeKe();

            foreach (DbParameter parameter in command.Parameters)
            {
                switch (parameter.DbType)
                {
                    case DbType.AnsiString:
                    case DbType.AnsiStringFixedLength:
                    case DbType.String:
                    case DbType.StringFixedLength:
                    case DbType.Xml:
                        parameter.Value =   parameter.Value is DBNull ? parameter.Value : parameter.Value.ApplyCorrectYeKe();
                        break;
                }
            }
        }
    }
در اینجا پیاده سازی متد الحاقی ApplyCorrectYeKe را که در کلاس YeKeInterceptor مورد استفاده قرار گرفت، ملاحظه می‌کنید.
در آن، CommandText و همچنین parameter.Valueها در صورت رشته‌ای بودن، اصلاح می‌شوند.
سربار این روش نسبت به روش‌های پیشین استفاده از Reflection کمتر است. همچنین اشیاء پیچیده و تو در تو را نیز بهتر پشتیبانی می‌کند؛ چون در مرحله Executing، کار پردازش این اشیاء پایان یافته و SQL خام نهایی آن در اختیار ما است.


نحوه‌ی استفاده از YeKeInterceptor

در آغاز برنامه (برای مثال متد Application_Start فایل Global.asax.cs برنامه‌های MVC )، سطر زیر را فراخوانی کنید:
 DbInterception.Add(new YeKeInterceptor());

یک مثال کامل برای دریافت
Sample32.cs
اشتراک‌ها
Angular Ivy چیست؟

Ivy is a complete rewrite of the compiler (and runtime) in order to:

  • 🚀reach better build times (with a more incremental compilation)
  • 🔥reach better build sizes (with a generated code more compatible with tree-shaking)
  • 🔓unlock new potential features (metaprogramming or higher order components, lazy loading of component instead of modules, a new change detection system not based on zone.js…) 
Angular Ivy چیست؟
اشتراک‌ها
نرم افزارهای selfContained در net core.

There's two ways to deploy a .NET Core application. There's FDD and SCD. Since TLAs (three letter acronyms) are stupid, that's Framework-dependent and Self-contained. When .NET Core is installed it ends up in C:\program files\dotnet on Windows, for example. In the "Shared" folder there's a bunch of .NET stuff that is, well, shared. There may be multiple folders, as you can see in my folder below. You can have many and multiple installs of .NET Core.  

نرم افزارهای selfContained در net core.
اشتراک‌ها
اسرارِ یک دات نت کار حرفه ای

Working as a .NET Professional is a tumultuous rollercoaster ride of emotional highs and crushing lows. It’s likely the same for other communities, with different flavors of success and failures. I have over a decade of .NET development work, and I am here to share some general mantras that have served me well. 

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

در اینجا غیر از مورد زمانبندی انجام پروژه سعی شده است به دیگر موارد غیره از قبیل شناخت نیازمندیها، نحوه بستن قرارداد، نحوه قیمت دهی و ... اشاره نشود.

 

در ابتدا در مورد موضوعات کلی و عمومی بحث می‌کنیم.

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

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

3- انتخاب معماری نرم­ افزار، معماری نرم ­افزار در اصل تعیین کننده نحوه قطعه بندی و توزیع تکه‌های نرم افزار، نحوه ارتباط اجزاء،، قابلیت تست پذیری، قابلیت نگهداری و قابلیت استفاده مجدد از کدهای تولید شده می­باشد. یکی از اهداف اساسی‌ای که باید در معماری نرم­‌افزار بدان توجه کرد، قابلیت استفاده مجدد از کد است. در یک معماری خوب ما قطعاتی درست خواهیم کرد که به‌راحتی می­توانیم از آن در نرم‌افزارهای دیگر نیز استفاده کنیم. البته قابلیت تست پذیری و قابلیت نگهداری نیز حداقل به همان اندازه اهمیت دارند. در این سایت موارد بسیار زیاد و کاملی جهت ساخت معماری مناسب و design patterns وجود دارد که می­توانید در اینجا یا اینجا مشاهده کنید.

 4- قابلیت اجرا بر روی پلتفرمهای مختلف، هرچند این مورد ممکن است بیشتر به نظر کارفرما بستگی داشته باشد، اما در کل اگر کارفرما بتواند سیستم را در پلتفرمهای مختلفی اجرا کند، راضی‌تر خواهد شد. اگر قصد فروش نرم‌­افزار طراحی شده را داشته باشیم، در اینصورت نیز می­توانیم کاربران پلتفرمهای مختلف را مورد هدف قرار دهیم یا سیستم را در سرورهای مختلفی میزبانی کنیم.

5- انتخاب سیستم بانک اطلاعاتی و نحوه ارتباط با آن. باید تصمیم بگیرید که از چند سیستم بانک اطلاعاتی، چگونه و به چه منظوری استفاده خواهید کرد. مواردی وجود دارند که سیستم را طوری طراحی کرد‌ه‌اند تا در زمان بهره برداری امکان انتخاب بانک‌های اطلاعاتی یا نحوه ذخیره اطلاعات برای مدیر سیستم وجود دارد. مثلا در BlogEngine.net میتوان انتخاب کرد که اطلاعات در SQL Server ذخیره شوند یا در سیستم فایل مبتنی بر XML . بحثهای بسیار زیادی در این سایت و کل فضای وب پیرامون نحوه انتخاب و استفاده از ORM ها، چگونگی معماری مناسب آن وجود دارد. بطور مثال همیشه بحث سر اینکه از الگوی Repository استفاده شود یا نشود وجود دارد! باید به خودمان پاسخ دهیم که آیا واقعاً نیاز است که سیستم را برای امکان استفاده از Orm‌های مختلف طراحی کنیم؟

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

7- میزان مشارکت دیگران در رفع نیازمندیهای کابران. ممکن است این گزینه در درجه اول زیاد با اهمیت جلوه ندهد، اما با تعمق در وبسایت‌ها و نرم‌­افزارهای بزرگ که هم اکنون در دنیا صاحب نامی شده‌اند می‌بینیم همه آنها تمهیداتی اندیشیده‌اند تا با وجود کپسوله کردن موارد پس زمینه، امکاناتی را در جهت مشارکت دیگران فراهم کنند. اکثر شبکه­‌های اجتماعی api هایی را مهیا کرده­ اند که افراد ثالث می­توانند از آنها استفاده کنند. اکثر سیستم‌های مدیریت محتوا و ابزارهای e-commerce تمهیداتی را برای راحتی ساخت plugin و api‌های برای راحتی برقراری ارتباط اشخاص ثالث اندیشیده‌اند. از نظر این جانب موارد 6 و 7 برای ادامه حیات و قابلیت رقابت پذیری پروژه از درجه اهمیت زیادی برخوردار است.

8- معماری Multi tenancy بلی یا خیر؟ Multi tenancy یک از بحثهای مهم رایانش ابری است. در این حالت فقط یک نمونه از نرم­ افزار در سمت سرور در حال اجراست ولی کاربر یا گروهی از کاربران دید یا تنظیمات متفاوتی از آن‌را دارند.

در ادامه به موارد فنی‌تری خواهیم پرداخت:

9- بحث انتخاب ابزار Dependency injection مناسب و مهیا سازی امکاناتی جهت هرچه راحت‌تر کردن امکان تنظیم و register کردن اشیا بدان. نحوه پیکربندی مناسب این مورد می­تواند کد نویسی را برایتان بسیار راحت کند. دات نت تیپس مطالب بسیاری را در این مورد ارائه داده است میتوانید اینجا را ببینید.

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

11- Logging. یک سیستم لاگر مناسب می­تواند وارنینگ‌ها و خطاهای بوجود آمده در سیستم را در یک رسانه ذخیره سازی حفظ کند و شما به عنوان توسعه دهنده می­توانید با مطالعه آن نسبت به رفع خطاهای احتمالی و بهبود در نسخه‌های آتی کمک بگیرید.

12- Audit logging یا Activity logging و Entity History. می­توانید کل یا برخی از فعالیتهای کاربر را در یک رسانه ذخیره سازی، ذخیره کنید، از قبیل زمان ورود و خروج، آی‌پی مورد استفاده، سیستم عامل، مرورگر، بازبینی از صفحه وغیره. همچنین در audit logging میتوانید زمانهای دقیق تغییرات مختلف موجود در موجودیتهای سیستم، فرد انجام دهنده تغییرات، سرویس انجام دهنده تغییرات، مدت زمان سپری شده و ... را ذخیره کرد. Entity History : ممکن است تصمیم بگیرید که کل اتفاقاتی را که برای یک موجودیت در طول زمان حیاتش در سیستم می‌افتد، ذخیره کنید.

13- Eventing ، Background Worker‌ها و Backgroudn jobs ( Scheduled tasks ). باید سیستم را طوری طراحی کرد که بتواند به تغییرات و اتفاقات افتاده در سیستم پاسخ دهد. همچنین این مورد یکی از نیازمندیهای معماری بر اساس پلاگین است. Background Worker‌ها در واقع کارهایی هستند که در پس زمینه انجام میشوند و نیازی نیست که کاربر برای اتمام آن منتظر بماند؛ مثلاً ارسال ایمیل خوش آمدگویی را میتوان با آن انجام داد. Background jobs کمی متفاوت هستند در واقع اینها فعالیتهای پس زمینه­ای هستند که ممکن است در فواصل زمانی مختلف اتفاق بیافتند، مثل پاکسازی کش در فواصل زمانی مناسب. در سیستمهای مختلف تمهیداتی برای ذخیره سازی فعالیتهایی که توسط background jobs انجام میشود اندیشیده می­شود.

14- پیکربندی صحیح نحوه ذخیره و بازیابی تنظیمات سیستم. در یک سیستم ممکن است شما تنظیمات متعددی را در اختیار کاربر و یا حتی خودتان قرار دهید. باید سیستم را طوری طراحی کنید که بتواند با راحت‌ترین و سریعترین روش ممکن به تنظیمات موجود دستیابی داشته باشد.

15- خطاهای کاربر را در نظر بگیریم، باید یادمان باشد کاربر ممکن الخطاست و ما برای رضایت مشتری و قابلیت اتکای هرچه بیشتر برنامه باید سیستم را طوری طراحی کنیم که امکان برگشت از خطا برای کاربر وجود داشته باشد. مثلاً در SoftDelete مواردی که حذف می­شوند در واقع به طور کامل از بانک اطلاعاتی حذف نمیشوند بلکه تیک حذف شده میخورند. پس امکان بازگردانی وجود خواهد داشت.

16- Mapping یا Object to object mapping. در توسعه شی‌‌ءگرا مخصوصاً در معماری‌هایی مثل MVC یا Domain driven در موارد بسیاری نیاز خواهید داشت که مقادیر اشیاء مختلفی را در اشیای دیگری کپی کنید. سیستمهای زیادی برای این کار موجود هستند. باید تلاش کرد ضمن اینکه یک سیستم مناسب انتخاب کنیم، باید تمهیدی بیاندیشیم که تنظیمات آن شامل کد نویسی هرچه کمتری باشد.

17- Authorization یا تعیین هویت. باید با مطالعه و بررسی، سیستم و ابزار مناسبی را برای هویت سنجی اعضاء، تنظیم نقشها و دسترسی‌های کاربران انتخاب کرد. باید امکان عضویت از طریق شبکه‌های اجتماعی مختلف را مورد بررسی قرار داد.

18- سرویس‌های Realtime. کاربری یکی از مطالب شما را می­‌پسندد و شما نوتیفیکشن آنرا سریع در صفحه‌­ای که باز کردید می­بینید. این یک مورد بسیار کوچکی از استفاده از سرویسهای realtime هست. ابزارهای مختلفی برای زبانها و فریم‌ورکهای مختلف وجود دارند؛ مثلاً میتوانید اینجا را مطالعه کنید.

19- هندل کردن خطاهای زمان اجرا، در سیستمهای قدیمی یکی از کابوس‌های کاربران، قطعی سیستم، هنگ کردن با کوچکترین خطا و موارد این چنینی بود. با تنظیم یک سیستم Exception handling مناسب هم میتوانیم گزارشاتی از خطاهای بوجود آمده را تهیه کنیم، هم میتوانیم کاربر را در جهت انجام صحیح کارها هدایت کنیم و هم از کرش بیجای نرم‌افزار جلوگیری کنیم.

20- استفاده از منابع ابری یا توزیع شده، امروزه برای بسیاری از کارها تمهیداتی از طرف شرکتهای بزرگ به صورت رایگان و یا غیر رایگان اندیشیده شده است که به راحتی می­توان از آنها استفاده کرد. برای نمونه میتوان از سرویسهای Email به عنوان ساده‌ترین و معمول‌ترین این سیستمها یاد کرد. اما امروزه شرکتها حتی امکاناتی جهت ذخیره سازی داده‌های blob (مجموعه ای از بایتها با حجم زیاد) را ارائه می­دهند؛ امکانات دیگری نظیر کم کردن حجم تصاویر، تبدیل انواع mime type‌ها و ...

21- امنیت، فریم‌ورکها اغلب موارد امنیتی پایه‌ای را به صورت مطلوب یا نسبتا مطلوبی رعایت می­کنند؛ ولی با این‌حال باید در مورد امنیت سیستمی که توسعه می‌دهیم مطالعه داشته باشیم و موارد امنیتی ضروری را رعایت کنیم و همیشه مواظب باشیم که آنها را رعایت کنیم.
نظرات مطالب
ارتقاء به NH 3.2 - قسمت دوم
مثال رو مجددا به روز کردم. Component mapping و همچنین یک روال نامگذاری سفارشی خودکار هم برای آن اضافه شد.
Component mapping مربوط به حالتی است که شما یک سری خواص را در یک کلاس تعریف می‌کنید اما قصد ندارید این‌ها واقعا تبدیل به یک جدول مجزا در بانک اطلاعاتی شوند. می‌خواهید این خواص دقیقا در همان جدول اصلی کنار مابقی خواص قرار گیرد. اما در طرف کدهای ما به شکل یک کلاس مجزا تعریف شود.
بازخوردهای دوره
انتقال خودکار Data Annotations از مدل‌ها به ViewModelهای ASP.NET MVC به کمک AutoMapper
نسخه 5.2.0 Automapper 
چگونه از member هایی که map نشده اند چشم پوشی کنیم؟
به عنوان مثال در LoginViewModel  تنها نیاز است نام کاربری و رمز عبور را دریافت کنیم اما در مدل اصلی یعنی User فیلد‌های دیگر هم وجود دارد.
برای این کار از کد زیر استفاده کردم اما باز هم با استثنا رخ می‌دهد.
   public LoginProfile()
   {
      CreateMap<LoginViewModel, User>().ForAllMembers(_ => _.Ignore());
      CreateMap<LoginViewModel, User>().ForMember(_ => _.UserName , __ => __.MapFrom(_ => _.UserName));
      CreateMap<LoginViewModel, User>().ForMember(_ => _.PasswordHash , __ => __.MapFrom(_ => _.Password));
   }

استثنا :
Unmapped members were found. Review the types and members below.
Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters
==========================================================================================
LoginViewModel -> User (Destination member list)
App.ViewModel.Enities.Identity.LoginViewModel -> App.DomainClasses.Entities.Identity.User (Destination member list)

Unmapped properties:
FirstName
LastName
IsSystemAccount
IsBan
RegisterDate
LastLoginDate
RowVersion
City
CityId
 // more ...

نظرات مطالب
خودکارسازی فرآیند نگاشت اشیاء در AutoMapper
ممنونم. مشکل قبل حل شد. 
 اگر ویومدل من بدینصورت باشه
public class MyViewModel : IHaveCustomMappings
    {
       
        public int SchedulerId { get; set; }
        public bool IsApplied { get; set; }
        public int Qty { get; set; }
        
        public void CreateMappings(IMapperConfigurationExpression configuration)
        {
            configuration.CreateMap<DomainModels.Models.Scheduler, MyViewModel>()
                .ForMember(dest => dest.SchedulerId, opt => opt.MapFrom(src => src.Id));
                    }
    }
خطایی صادر میکندبا این عنوان: 
Unmapped members were found. Review the types and members below.
Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters
اگر دو فیلد IsApplied  ,    Qty   هم در متد  CreateMappings بصورت دستی map کنم خطایی صادر نمیشود. در صورتیکه قبلا با اتوماتیک مپ میشدند. آیا تغییری در AutoMapperRegistry  نیاز هست؟