مطالب
آشنایی با نسخه بندی و چرخه انتشار نرم افزارها
نسخه بندی و چرخه انتشار یک نرم افزار، اهمیت زیادی در ارائه یک نرم افزار خوب دارد. هر چه نرم افزار شما بزرگ‌تر و از کتابخانه‌های بیشتری در تولید آن استفاده شده باشد، در بروز رسانی و نسخه بندی آن دقت بیشتری باید داشت و کار دشوار‌تری است. اما چگونه به بهترین روش، نسخه بندی نرم افرار خود را مدیریت نمایید.

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

چرخه انتشار نرم افزار:
 چرخه انتشار نرم افزار از زمان شروع کد نویسی تا عرضه نسخه نهایی می‌باشد که شامل چندین مرحله و عرضه نرم افزار می‌باشد.
  1. Pre-alpha
    این مرحله شامل تمام فعالیت‌های انجام شده قبل از مرحله تست می‌باشد. در این دوره آنالیز نیازمندیها، طراحی نرم افزار، توسعه نرم افزار و حتی تست واحد باشد. در نرم افزار‌های سورس باز چندین نسخه قبل از آلفا ممکن است عرضه شوند.
  2. Alpha
    این مرحله شامل همه فعالیت‌ها از زمان شروع تست می‌باشد. البته منظور از تست، تست تیمی و تست خود نرم افزار می‌باشد. نرم افزار‌های آلفا هنوز ممکن است خطا و اشکالاتی داشته باشند و ممکن است اطلاعات شما از بین رود. در این مرحله امکانات جدیدی مرتبا به نرم افزار اضافه می‌گردد.
  3. Beta
    نرم افزار بتا، همه قابلیت‌های آن تکمیل شده و خطا‌های زیادی برای کامل شدن نرم افزار وجود دارد. در این مرحله بیشتر به تست کاهش تاثیرات به کاربران و تست کارایی دقت می‌شود. نسخه بتا، اولین نسخه‌ای خواهد بود که بیرون شرکت و یا سازمان در دسترس قرار می‌گیرد. برخی توسعه دهندگان به این مرحله preview، technical preview یا early access نیز می‌گویند.
  4. Release candidate
    در این مرحله نرم افزار، آماده عرضه به مصرف کنندگان است و نرم افزارهایی مثل سیستم عامل‌های ویندوز در دسترس تولید کنندگان قرار گرفته تا با جدید‌ترین سخت افزار خود یکپارچه شوند.
  5.  General availability (GA)
    در این مرحله، عرضه عمومی نرم افزار و بازاریابی و فروش نرم افزار مد نظر است و علاوه بر این تست امنیتی و در نرم افزار‌های خیلی بزرگ عرضه جهانی صورت می‌گیرد 
مراحلی همچون عرضه در وب و پشتیبانی نیز وجود دارند.

نسخه بندی نرم افزار:
برنامه‌های ویندوزی یا وب در ویژوال استادیو یک فایل AssemblyInfo دارند که در قسمت آخر آن، اطلاعات مربوط به نسخه نرم افزار ذخیره می‌شود. هر نسخه نرم افزار شامل چهار عدد می‌باشد که با نقطه از هم جدا شده است.
  • Major Version
    وقتی افزایش می‌یابد که تغییرات قابل توجهی در نرم افزار ایجاد شود
  • Minor Version
    وقتی افزایش یابد که ویژگی جزئی یا اصلاحات قابل توجهی به نرم افزار ایجاد شود.
  • Build Number
    به ازای هر بار ساخته شدن پروژه افزایش می‌یابد.
  • Revision
    وقتی افزایش می‌یابد که نواقص و باگ‌های کوچکی رفع شوند. 
وقتی که major یا minor افزایش یابد می‌تواند با کلماتی همچون alpha، beta یا release candidate همراه شود.در اکثر برنامه‌های تجاری اولین شمارهٔ انتشار یک محصول از نسحهٔ شمارهٔ یک شروع می‌شود. ترتیب نسخه بندی هم ممکن است تغییر یابد
major.minor[.build[.reversion]]
یا
major.minor[.maintenance[.build]]
نسخه بندی مایکروسافت:
اگر به نسخه برنامه Office توجه کرده باشید مثلا Office 2013 نسخه 15.0.4481.1508 می‌باشد که در این روش از تاریخ شروع پروژه و تعداد ماه‌ها یا روز‌ها و یا ثانیه‌ها با یک الگوریتم خاص برای تولید نسخه نرم افزار استفاده می‌شود.
نسخه بندی معنایی:

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

علیرغم آن، مهم است که این API، روشن و دقیق باشد. هنگامیکه API عمومی خود را تعیین کردید، تغییرات برنامه شما بر روی نسخه API عمومی تاثیر خواهد داشت و آنرا افزایش خواهد داد. بر این اساس، این مدل نسخه‌بندی را در نظر بگیرید: X.Y.Z یعنی (Major.Minor.Patch).

رفع حفره‌هایی که بر روی API عمومی تاثیر نمی‌گذارند، مقدار Patch را افزایش می‌دهند، تغییرات جدیدی که سازگار با نسخه قبلی است، مقدار Minor را افزایش می‌دهند و تغییرات جدیدی که کاملا بدیع هستند و به نحوی با تغییرات قبلی سازگار نیستند مقدار Major را افزایش می‌دهند. 

  1. نرم‌افزارهایی که از نسخه بندی معنایی استفاده می‌کنند، باید یک API عمومی داشته باشند. این API می‌تواند در خود کد یا و یا به طور صریح در مستندات باشد که باید دقیق و جامع باشد.
  2. یک شماره نسخه صحیح باید به شکل X.Y.Z باشد که در آن X،Y و Z اعداد صحیح غیر منفی هستند. X نسخه‌ی Major می‌باشد، Y نسخه‌ی Minor و Z نسخه‌ی Patch می‌باشد. هر عنصر باید یک به یک و بصورت عددی افزایش پیدا کند. به عنوان مثال: 1.9.0 -> 1.10.0 -> 1.11.0
  3. هنگامی که به یک نسخه‌ی Major یک واحد اضافه می‌شود، نسخه‌ی Minor و Patch باید به حالت 0 (صفر) تنظیم مجدد گردد. هنگامی که به شماره نسخه‌ی Minor یک واحد اضافه می‌شود، نسخه‌ی Patch باید به حالت 0 (صفر) تنظیم مجدد شود. به عنوان مثال: 1.1.3 -> 2.0.0 و 2.1.7 -> 2.2.0
  4. هنگامیکه یک نسخه از یک کتابخانه منتشر می‌شود، محتوای کتابخانه مورد نظر نباید به هیچ وجه تغییری داشته باشد. هر گونه تغییر جدیدی باید در قالب یک نسخه جدید انتشار پیدا کند.
  5. نسخه‌ی Major صفر (0.Y.Z) برای توسعه‌ی اولیه است. هر چیزی ممکن است در هر زمان تغییر یابد. API عمومی را نباید پایدار در نظر گرفت.
  6. نسخه 1.0.0 در حقیقت API عمومی را تعریف می‌کند. چگونگی تغییر و افزایش هر یک از نسخه‌ها بعد از انتشار این نسخه، وابسته به API عمومی و تغییرات آن می‌باشد.
  7. نسخه Patch یا (x.y.Z | x > 0) فقط در صورتی باید افزایش پیدا کند که تغییرات ایجاد شده در حد برطرف کردن حفره‌های نرم‌افزار باشد. برطرف کردن حفره‌های نرم‌افزار شامل اصلاح رفتارهای اشتباه در نرم‌افزار می‌باشد.
  8. نسخه Minor یا (x.Y.z | x > 0) فقط در صورتی افزایش پیدا خواهد کرد که تغییرات جدید و سازگار با نسخه قبلی ایجاد شود. همچنین این نسخه باید افزایش پیدا کند اگر بخشی از فعالیت‌ها و یا رفتارهای قبلی نرم‌افزار به عنوان فعالیت منقرض شده اعلام شود. همچنین این نسخه می‌تواند افزایش پیدا کند اگر تغییرات مهم و حیاتی از طریق کد خصوصی ایجاد و اعمال گردد. تغییرات این نسخه می‌تواند شامل تغییرات نسخه Patch هم باشد. توجه به این نکته ضروری است که در صورت افزایش نسخه Minor، نسخه Patch باید به 0 (صفر) تغییر پیدا کند.
  9. نسخه Major یا (X.y.z | X > 0) در صورتی افزایش پیدا خواهد کرد که تغییرات جدید و ناهمخوان با نسخه فعلی در نرم‌افزار اعمال شود. تغییرات در این نسخه می‌تواند شامل تغییراتی در سطح نسخه Minor و Patch نیز باشد. باید به این نکته توجه شود که در صورت افزایش نسخه Major، نسخه‌های Minor و Patch باید به 0 (صفر) تغییر پیدا کنند.
  10. یک نسخه قبل از انتشار می‌تواند توسط یک خط تیره (dash)، بعد از نسخه Patch (یعنی در انتهای نسخه) که انواع با نقطه (dot) از هم جدا می‌شوند، نشان داده شود. نشان‌گر نسخه قبل از انتشار باید شامل حروف، اعداد و خط تیره باشد [0-9A-Za-z-]. باید به این نکته دفت داشت که نسخه‌های قبل از انتشار خود به تنهایی یک انتشار به حساب می‌آیند اما اولویت و اهمیت نسخه‌های عادی را ندارد. برای مثال: 1.0.0-alpha ، 1.0.0-alpha.1 ، 1.0.0-0.3.7 ، 1.0.0-x.7.z.92
  11. یک نسخه Build می‌تواند توسط یک علامت مثبت (+)، بعد از نسخه Patch یا نسخه قبل از انتشار (یعنی در انتهای نسخه) که انواع آن با نقطه (dot) از هم جدا می‌شوند، نشان داده شود. نشان‌گر نسخه Build باید شامل حروف، اعداد و خط تیره باشد [0-9A-Za-z-]. باید به این نکته دقت داشت که نسخه‌های Build خود به تنهایی یک انتشار به حساب می‌آیند و اولویت و اهمیت بیشتری نسبت به نسخه‌های عادی دارند. برای مثال: 1.0.0+build.1 ، 1.3.7+build.11.e0f985a
  12. اولویت‌بندی نسخه‌ها باید توسط جداسازی بخش‌های مختلف یک نسخه به اجزای تشکیل دهنده آن یعنی Minor، Major، Patch، نسخه قبل از انتشار و نسخه Build و ترتیب اولویت بندی آن‌ها صورت گیرد. نسخه‌های Minor، Major و Patch باید بصورت عددی مقایسه شوند. مقایسه نسخه‌های قبل از انتشار و نسخه Build باید توسط بخش‌های مختلف که توسط جداکننده‌ها (نقطه‌های جداکننده) تفکیک شده است، به این شکل سنجیده شود:

بخش‌هایی که فقط حاوی عدد هستند، بصورت عددی مقایسه می‌شوند و بخش‌هایی که حاری حروف و یا خط تیره هستند بصورت الفبایی مقایسه خواهند شد.

بخش‌های عددی همواره اولویت پایین‌تری نسبت به بخش‌های غیر عددی دارند. برای مثال:

1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0-rc.1+build.1 < 1.0.0 < 1.0.0+0.3.7 < 1.3.7+build < 1.3.7+build.2.b8f12d7 < 1.3.7+build.11.e0f985a

منبع نسخه بندی معنایی : semver.org

 
نظرات مطالب
اجبار به استفاده‌ی از HTTPS در حین توسعه‌ی برنامه‌های ASP.NET Core 2.1
با سلام؛ من نسخه dotnet-sdk-2.2.402-win-x64 را روی ویندوز سرور نصب میکنم و از دستور certmgr.msc برای دیدنش استفاده می‌کنم؛ چیزی رو نمایش نمیده. ولی روی سیستم خودم درست نصب شده، مشکل روی سرور هست. آیا روی سرور تنظیم خاصی رو باید انجام بدم؟ از دستور dotnet --info استفاده میکنم، میگه sdk نصب نیست؛ در صورتی که نصب هست.
  >dotnet --in

Host (useful for support):
  Version: 2.2.7
  Commit:  b1e29ae826

.NET Core SDKs installed:
  No SDKs were found.

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.2.5 [C:\Program Files (x86)\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.7 [C:\Program Files (x86)\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.2.5 [C:\Program Files (x86)\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.7 [C:\Program Files (x86)\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.2.5 [C:\Program Files (x86)\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.7 [C:\Program Files (x86)\dotnet\shared\Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
مطالب
اختصاصی کردن Razor برای #C در MVC با استفاده از Extension Method
در این مقاله ما میخواهیم RazorViewEngine را با استفاده از یک Extension Method  به گونه ای تنظیم کنیم که فقط به دنبال View‌هایی که مربوط به C# هستند بگردد. در ابتدای مقاله توضیح خلاصه ای درباره Extension Method خواهیم داشت و سپس نحوه اختصاصی کردن Razor برای C# را خواهیم دید.
Extension Method‌ها بسیار کارآمد هستند و  نحوه ایجاد و استفاده از آنها بسیار راحت است. به گونه ای که میتوان آنها را حتی برای کلاس‌های از قبل تعریف شده .Net نیز ایجاد کرد و در سرتاسر برنامه از آن استفاده کرد.
با مثالی ساده نحوه ایجاد و استفاده از Extension Method را میبینیم. در این مثال ما سعی داریم متدی برای کلاس string در .Net بنویسیم که دو رشته را به هم بچسباند.
1. ابتدا کلاسی در دایرکتوری دلخواه ایجاد میکنیم.
namespace ApplicationTest01.Utilities
{
    public class StringHelper
    {
    }
}
2. سپس متد مورد نظر را مینویسیم:
namespace ApplicationTest01.Utilities
{
    public class StringHelper
    {
        public string StringConcatenate(string firstPhrase, string secondPhrase)
        {
            return firstPhrase + secondPhrase;
        }
    }
}
3. کلاس و متدی که در آن تعریف میکنیم بایستی public و static باشند. namespace کلاس را نیز به namespace کلاس string در .Net (یعنی System) تغییر میدهیم.
namespace System
{
    public static class StringHelper
    {
        public static string StringConcatenate(string firstPhrase, string secondPhrase)
        {
            return firstPhrase + secondPhrase;
        }
    }
}
4. در Extension Method‌ها ورودی اول تابع به پارامتری اشاره دارد که قرار است هنگام استفاده از آن (یا صدا زدن آن) متد، عملیات مورد نظر را روی آن اجرا کند. به همین جهت عبارت this را به پارامتر ورودی اول تابع میدهیم.
namespace System
{
    public static class StringHelper
    {
        public static string StringConcatenate(this string firstPhrase, string secondPhrase)
        {
            return firstPhrase + secondPhrase;
        }
    }
}
برای استفاده از این متد کافیست پس از یک عبارت string متد را فراخوانی کنیم:
        public ActionResult Index()
        {
            "1234".StringConcatenate("567");
            string s1 = "dotnet";
            string s2 = "tips";
            s1.StringConcatenate(s2);
            return View();
        }
همانطور که میبینید در ظاهر تابع فقط یک ورودی دارد ولی ما دو ورودی برای آن در نظر گرفتیم. در واقع ورودی اول تابع قبل از "." (دات) آمده است و عبارت this به آن اشاره دارد.
برای اختصاصی کردن RazorViewEngine برای C#، مشابه روند فوق یک Extension Method ایجاد میکنیم که namespace کلاس آن با namespace کلاس RazorViewEngine (یعنی System.Web.Mvc ) یکی باشد. خروجی Extension Method ما از نوع  RazorViewEngine میباشد:
namespace System.Web.Mvc
{
    public static class EngineFilter
    {
        public static RazorViewEngine DisableVbhtml(this RazorViewEngine engine)
        {
            return engine;
        }
    }
}
از آن جایی که کلاس RazorViewEngine برای شناسایی view‌ها شامل Peroperty هایی از جنس []string می‌باشد، ابتدا متدی ساده به نام FilterOutVbhtml برای فیلتر کردن string‌های حاوی عبارت "vbhtml" مینویسیم.
namespace System.Web.Mvc
{
    public static class EngineFilter
    {
        public static RazorViewEngine DisableVbhtml(this RazorViewEngine engine)
        {
            return engine;
        }
 
        private static string[] FilterOutVbhtml(string[] source)
        {
            return source.Where(s => !s.Contains("vbhtml")).ToArray();
        }
    }
}
در ادامه، در بدنه متد DisableVbhtml پروپرتی‌های RazorViewEngine را فرا خوانی کرده و با استفاده از متد FilterOutVbhtml آنها را فیلتر میکنیم.
namespace System.Web.Mvc
{
    public static class EngineFilter
    {
        public static RazorViewEngine DisableVbhtml(this RazorViewEngine engine)
        {
            engine.AreaViewLocationFormats = FilterOutVbhtml(engine.AreaViewLocationFormats);
            engine.AreaMasterLocationFormats = FilterOutVbhtml(engine.AreaMasterLocationFormats);
            engine.AreaPartialViewLocationFormats = FilterOutVbhtml(engine.AreaPartialViewLocationFormats);
            engine.ViewLocationFormats = FilterOutVbhtml(engine.ViewLocationFormats);
            engine.MasterLocationFormats = FilterOutVbhtml(engine.MasterLocationFormats);
            engine.PartialViewLocationFormats = FilterOutVbhtml(engine.PartialViewLocationFormats);
            engine.FileExtensions = FilterOutVbhtml(engine.FileExtensions);
            return engine;
        }
 
        private static string[] FilterOutVbhtml(string[] source)
        {
            return source.Where(s => !s.Contains("vbhtml")).ToArray();
        }
    }
}
سپس در فایل Global.asax در Application_Start یکبار ViewEngine‌ها را حذف میکنیم -Engine مربوط به aspx به صورت پیش فرض فعال میباشد- و سپس RazorViewEngine را به همراه فراخوانی Extension Method خودمان به ViewEngine‌ها اضافه میکنیم.
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngine().DisableVbhtml());
امیدوارم مطالب فوق برای شما مفید و کارآمد باشد.
منبع: stackoverflow.com
نظرات مطالب
معرفی افزونه CAT.NET
یک نکته:
همیشه IDE ویژوال استودیو را در حالت safe mode و بدون افزونه‌ها هم می‌شود اجرا کرد به صورت زیر:
devenv /safemode
دستور فوق را در run ویندوز نوشته و enter‌ کنید. به این صورت IDE بدون افزونه‌ها بارگذاری می‌شود.
اشتراک‌ها
مستندات ASP.NET 5
    Getting Started
        Installing ASP.NET 5 On Windows
        Installing ASP.NET 5 On Mac OS X
        Installing ASP.NET 5 On Linux
        Choosing the Right .NET For You on the Server
    Tutorials
        Your First ASP.NET 5 Application Using Visual Studio
        Your First ASP.NET 5 Application on a Mac
        Publish to an Azure Web App using Visual Studio
    Conceptual Overview
        Introduction to ASP.NET 5
        Introducing .NET Core
        DNX Overview
        Understanding ASP.NET 5 Web Apps
    Fundamentals
        Working with Static Files
        Routing
        Configuration
        Dependency Injection
        Diagnostics
        Working with Multiple Environments
        OWIN
    .NET Execution Environment (DNX)
        DNX Overview
        Creating a Cross-Platform Console App with DNX
        Working with DNX Projects
        Using Commands
    Publishing and Deployment
        Publish to a Docker Image
    Client-Side Development
        Grunt and Gulp: Task Runners
        Manage Client-Side Packages with Bower
        Building Beautiful, Responsive Sites with Bootstrap
        Knockout.js MVVM Framework
        Styling Applications with Less, Sass, and Font Awesome
    Security
        Enabling authenication using external providers
        Account Confirmation and Password Recovery with ASP.NET Identity
        Two-factor authenication with SMS using ASP.NET Identity
        Data Protection
    Extensibility
        Writing Middleware
مستندات ASP.NET 5
نظرات مطالب
اجرای سرویسهای NodeJS در ASP.NET Core
منظورم این نبود که حتما سرباری اضافه کنه ولی باتوجه به اینکه اجرای سرویس نود نیاز به پراسس مجزایی داره به صورت پیش فرض برای اجرا شدن ... اینکه node و dotnet همزمان باهم کارکنند گفتم شاید سرباری اضافه کنه... چون اطلاعی هنوز از نحوه اجرای سرویس نود در asp.net ندارم ... گفتم شاید دوستان اطلاعات بهتری داشته باشند که در background چه اتفاقی می‌افته؟ به طور کلی معماری این امکان به چه شکل هست؟
نظرات مطالب
بررسی برخی تغییرات در Angular 8
TypeScript 3.4.x Support
انگیولار 8، از (3.4) typescript و نگارش‌های بالاتر پشتیبانی می‌کند. اگر می‌خواهیم از انگیولار 8 برای App ‌های جدید استفاده کنیم، نیاز است typescript را به نگارش 3.4 و یا بالاتر ارتقاء دهیم.

Ivy Rendering Engine
یکی از مهمترین و مورد انتظارترین ویژگی‌های انگیولار 8، موتور IVY می‌باشد. IVY یک Angular Compiler جدید می‌باشد و هم چنین یک ابزار که به عنوان یک rendering pipeline جدید عمل می‌کند. مزیت Ivy این است که به طور قابل توجهی bundle‌های کوچکی را تولید می‌کند (سایز bundle‌ها را کاهش میدهد)  و همچنین به آسانی می‌تواند کامپایل سریعی را انجام دهد. بنابراین Ivy، اساس نوآوری در دنیای انگیولار می‌باشد. Ivy در انگیولار 8 به صورت پیش نمایشی می‌باشد. هدف اصلی این نسخه این است که بازخورد‌ها را از جامعه توسعه دهندگان انگیولار، مرتبط با Ivy دریافت کند. پیشنهاد شده است که در این روزها از Ivy برای حالت ارائه‌ی نهایی (Production) استفاده نشود.


در ngconf  سال  2019، (Brad Green)، هدایت کننده فنی تیم انگیولار گفت که در صورت استفاده از Ivy، از مزایای زیر برخوردار هستیم: 

  • کامپایل سریعتری را فراهم می‌کند (انتشار در انگیولار  9) 
  • بررسی type  در قالب‌ها، خیلی بیشتر بهبود یافته است؛ به‌گونه‌ای که می‌توان خطاهای بیشتری را در زمان build گرفت که باعث می‌شود کاربران در زمان runtime به آن خطاها برخورد نکنند (انتشار در انگیولار 9). 
  • bundle‌های با سایز کوچکتری در مقایسه با سایز bundle‌های کامپایل شده‌ی جاری 
  • کد‌های تولید شده توسط  Angular compiler، بسیار آسان‌تر، برای خواندن و درک انسان است. 
  • آخرین و مهمترین ویژگی مورد علاقه من این است که می‌توان قالب‌ها (templates) را debug کرد. من یقین دارم که این ویژگی توسط تعداد زیادی از توسعه دهندگان مورد توجه قرار خواهد گرفت .
همانطور که در متن بالا گفته شده است اگر بخواهید در یک پروژه‌ی انگیولار، Ivy  را شامل کنید، علاوه بر حالت گفته شده‌ی در متن‌، می‌توانید به صورت دستی تنظیم بالا را به پروژه‌ی انگیولار اضافه کنید (بعد از ارتقاء به انگیولار 8). پیشنهاد شده‌است که اگر می‌خواهیم از Ivy  در Application ‌ها استفاده کنیم، Application را در حالت debug، همراه با AOT compilation اجرا کنید:
ng serve --aot

Bye Bye @angular/http
از نگارش 8 انگیولار، پشتیبانی از angular/http@ متوقف می‌شود. تا نگارش 7 انگیولار، امکان استفاده‌ی از angular/http@ برای ما فراهم بود؛ اما استفاده‌ی از angular/http@ منسوخ شده بود و در نگارش 4 انگیولار یک فراخوانی امن و کارآمد HTTP را با استفاده از  angular/common/http@  فراهم کردند. 

PNPM Support
در نگارش 8 انگیولار، پشتیبانی از یک package manager جدید به نام PNPM وجود دارد که شامل NPM و Yarn می‌باشد.

Support for New Builders/Architect API
نگارش جدید Angular CLI  این اجازه را به ما می‌دهد که از نسخه‌ی جدید Builders که به عنوان Architect API شناخته می‌شود، استفاده کنیم. انگیولار از Builders API برای اجرای  عملیاتی مثل server, build, test, lint و e2e استفاده می‌کند. در ضمن می‌توانیم از builders در فایل angular.json استفاده کنیم: 
"projects": {  
  "app-name": {  
    "architect": {  
      "build": {  
        "builder": "@angular-devkit/build-angular:browser",  
      },  
      "serve": {  
        "builder": "@angular-devkit/build-angular:dev-server",  
      },  
      "test": {  
        "builder": "@angular-devkit/build-angular:karma",  
      },  
      "lint": {  
        "builder": "@angular-devkit/build-angular:tslint",  
      },  
      "e2e": {  
        "builder": "@angular-devkit/build-angular:protractor",  
      }  
    }  
  }  
}
نظرات مطالب
سفارشی سازی ASP.NET Core Identity - قسمت سوم - نرمال سازها و اعتبارسنج‌ها
یک نکته‌ی تکمیلی: چگونه پس از نصب SDK 3x جدید، بتوانیم همان پروژه‌ی قبلی را بدون به روز رسانی یا هیچگونه تغییری در آن، باز هم استفاده کنیم؟

با توجه به اینکه امضای یکسری از اینترفیس‌های نگارش 3x با 2x یکی نیست (مانند ILookupNormalizer)، پس از نصب SDK 3x، دیگر قادر به اجرای برنامه‌های 2x خود نخواهید شد؛ چون پروژه‌های NET Core. همواره از آخرین نگارش SDK نصب شده استفاده می‌کنند. برای قفل کردن شماره SDK یک Solution به نگارش 2x به صورت زیر عمل کنید:
dotnet --list-sdks
dotnet new globaljson --sdk-version 2.2.106
دستور اول لیست SDKهای نصب شده را نمایش می‌دهد و دستور دوم یک فایل global.json جدید را بر اساس شماره‌ای که از طریق اجرای دستور اول یافته‌اید، تولید می‌کند. این فایل باید در ریشه‌ی Solution قرار گیرد.
مطالب
آموزش (jQuery) جی کوئری 5#
در ادامه مطلب قبلی  آموزش (jQuery) جی کوئری 4# به ادامه بحث  می‌پردازیم.
در پست قبل به بررسی انتخاب عناصر بر اساس موقعیت پرداختیم، در این پست به بحث "استفاده از انتخاب کننده‌های سفارشی jQuery" خواهیم پرداخت.

4-1- استفاده از انتخاب کننده‌های سفارشی jQuery
در پست‌های قبلی (^ و ^ ) تعدادی از انتخاب کننده‌های CSS که هر کدامشان موجب قدرت و انعطاف پذیری انتخاب اشیا موجود در صفحه می‌شوند را بررسی کردیم. با این وجود  فیلتر‌های انتخاب کننده قدرتمندتری وجود دارند که توانایی ما را برای انتخاب بیشتر می‌کنند.
به عنوان مثال اگر بخواهید از میان تمام چک باکس ها، گزینه هایی را که تیک خورده اند انتخاب نمایید، از آنجا که تلاش برای مطابقت حالت‌های اولیه کنترل‌های HTML را بررسی می‌کنیم، jQuery انتخابگر سفارشی checked: را پیشنهاد می‌کند، که مجموعه از عناصر را که خاصیت checked آنها فعال باشد را برای ما برمی گرداند. براس مثال انتخاب کننده input تمامی المان‌های <input> را انتخاب می‌کند، و انتخاب کننده input:checked تمامی inputهایی را انتخاب می‌کند که checked هستند. انتخاب کننده سفارشی checked:یک انتخاب کننده خصوصیت CSS عمل می‌کند (مانند [foo=bar]). ترکیب این انتخاب کننده‌ها می‌تواند قدرت بیشتری به ما بدهد، انتخاب کننده هایی مانند radio:checked: و checkbox:checked: .
همانطور هم که قبلا بیان شد، jQuery علاوه بر پشتیبانی از انتخاب کننده‌های CSS تعدادی انتخاب کننده سفارشی را نیز شامل می‌شود که در جدول 3-2 شرح داده شده است.

جدول 3-2: انتخاب کننده‌های سفارشی jQuery
 توضیح انتخاب کننده
 عناصری را انتخاب می‌کند که تحت کنترل انیمیشن می‌باشند. در پست‌های بعدی انیمیشن‌ها توضیح داده می‌شوند.
animated:
 عناصر دکمه را انتخاب می‌کند، عناصری مانند (input[type=submit]، input[type=reset]، input[type=button]،  یا button) 
button:
عناصر Checkbox را انتخاب می‌کند، مانند ([input[type=checkbox).
checkbox:
عناصر checkboxها یا دکمه‌های رادیویی را انتخاب می‌کند که در حالت انتخاب باشند.
checked:
عناصری ر انتخاب می‌کند که دارای عبارت foo باشند.
contains(foo) //c:
عناصر در حالت disabled را انتخاب می‌کند. disabled:
عناصر در حالت enabledرا انتخاب می‌کند.
enabled:
عناصر فایل را انتخاب می‌کند، مانند ([input[type=file).
file:
عناصر هدر مانند h1 تا h6 را انتخاب می‌کند.
header:
عناصر مخفی شده را انتهاب می‌کند.
hidden:
عناصر تصویر را انتخاب می‌کند، مانند ([input[type=image).
image:
عناصر فرم مانند input ، select، textarea، button را انتخاب می‌کند.
input:
انتخاب کننده‌ها را برعکس می‌کند.
not(filter)//c:
عناصری که فرزندی دارند را انتخاب می‌کند.
parent:
عناصر password را انتخاب می‌کند، مانند ([input[type=password). password:
عناصر radio را انتخاب می‌کند، مانند ([input[type=radio). 
radio:
دکمه‌های reset را انتخاب می‌کند، مانند  ([input[type=reset یا [button[type=reset).
raset:
عناصری (عناصر option) را انتخاب می‌کند که در وضعیت selected قراردارند.
selected:
دکمه‌های submit را انتخاب می‌کند، مانند  ([input[type=submit یا [button[type=submit). submit:
عناصر text را انتخاب می‌کند، مانند ([input[type=text).   
text:
عناصری را که در وضعیت visibleباشند انتخاب می‌کند.
visible:
بسیاری از انتخاب کننده‌های سفارشی jQuery بررسی شده برای انتخاب عناصر فرم ورود اطلاعات کاربر استفاده می‌شوند. این فیلتر‌ها قابلیت ادغام را دارند، برای مثال در زیر دستوری را به منظور انتخاب آن دسته از گزینه‌های Checkbox که تیک خورده اند و فعال هستند را مشاهده می‌کنید:
:checkbox:checked:enabled

این فیلتر‌ها و انتخاب کننده‌ها کاربردهای وسیعی در صفحات اینترنتی دارند، آیا آنها حالت معکوسی نیز دارند؟

استفاده از فیلتر not:
برای آنکه نتیجه انتخاب کننده‌ها را معکوس کنیم می‌توانیم از این فیلتر استفاده کنیم. برای مثال دستور زیر تمام عناصری را که checkBox نیستند را انتخاب می‌کند:
input:not(:checkbox)
اما استفاده از این فیلتر دقت زیادی را می‌طلبد زیرا به سادگی ممکن است با نتیجه ای غیر منتظره مواجه شویم.

استفاده از فیلتر has:
در اینجا دیدیم که CSS انتخاب کننده قدرتمندی را ارایه کرده است که فرزندران یک عنصر را در هر سطحی که باشند (حتی اگر فرزند مستقیم هم نباشند) انتخاب می‌کند. برای مثال دستور زیر تمام عناصر span را که در div معرفی شده باشند را انتخاب می‌کند:
div span

اما اگر بخواهیم انتخابی برعکس این انتخاب داشته باشیم، باید چه کنیم؟ برای این کار باید تمام divهایی که دارای عنصر span می‌باشد را انتخاب کرد. برای چنین انتخابی از فیلتر has: استفاده می‌کنیم. به دستور زیر توجه نمایید، این دستور تمام عناصر div را که در آنها عنصر span معرفی شده است را انتخاب می‌کند:
div:has(span)

برای برخی انتخاب‌های پیچیده و مشکل، این فیلتر و مکانیزم بسیار کارا می‌باشد و به سادگی ما را به هدف دلخواه می‌رساند. فرض کنید می‌خواهیم آن خانه از جدول که دارای یک عنصر عکس خاص می‌باشد را پیدا کنیم. با توجه به این نکته که آن عکس از طریق مقدار src قابل تشخیص می‌باشد، با استفاده از فیلتر has: دستوری مانند زیر می‌نویسیم:
$('tr:has(img[src$="foo.png"])')

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


موفق و موید باشید.
مطالب
قابلیت چند زبانه و Localization در AngularJs بخش اول: معرفی angular-translate
در این مقاله قصد داریم با استفاده از ماژول Angular-Translate امکان ایجاد یک سیستم چند زبانه را تشریح کنیم.
angular-translate یک ماژول توسعه داده شده AngularJs میباشد که با استفاده از i18n و l10n، قابلیت چند زبانه را به صورت Lazy Loading برای شما فراهم می‌کند.
شما میتوانید با خط فرمان زیر، در بخش package-manager، کتابخانه‌های مربوط به angular-translate را به نرم افزار خود اضافه نمایید:
Install-Package AngularTranslate
تکه کد زیر یک مثال ساده از angular translate است که در صفحه‌ی اصلی این ماژول قرار داده شده است.
var app = angular.module('at', ['pascalprecht.translate']);

app.config(function ($translateProvider) {
  $translateProvider.translations('en', {
    TITLE: 'Hello',
    FOO: 'This is a paragraph.',
    BUTTON_LANG_EN: 'english',
    BUTTON_LANG_DE: 'german'
  });
  $translateProvider.translations('de', {
    TITLE: 'Hallo',
    FOO: 'Dies ist ein Paragraph.',
    BUTTON_LANG_EN: 'englisch',
    BUTTON_LANG_DE: 'deutsch'
  });
  $translateProvider.preferredLanguage('en');
});

app.controller('Ctrl', function ($scope, $translate) {
  $scope.changeLanguage = function (key) {
    $translate.use(key);
  };
});
با نگاهی ساده به تکه کد فوق می‌توان مراحل افزودن این ماژول و استفاده از آن را به صورت زیر ساده کرد:
1. وابستگی pascalprecht.translate را در بخش angular.module قرار می‌دهیم.
2. در بخش app.config وابستگی translateProvider$ را تزریق می‌کنیم.
3. با استفاده از رویه‌ی translations زبان‌های مختلف را به همراه لیبل آنها اضافه می‌نماییم. توجه کنید که امکان خواندن این ریسورس‌ها از فایل txt و json نیز وجود دارد.
4. با استفاده از رویه‌ی preferredLanguage زبان پیش فرض سیستم تعیین می‌گردد.
5. در کنترلر فراخواننده‌ی تغییر زبان، باید وابستگی translate$ را اضافه نماییم.
6. با استفاده از رویه‌ی use زبان مورد نظر را تغییر می‌دهیم.
تمامی مراحل فوق در قالب یک  پروژه نمونه در Plunker  قرار داده شده است.
در بخش بعدی به بررسی اجمالی قابلیت‌های این ماژول خواهیم پرداخت.