معرفی برنامهی Subtitle Tools
این شباهت اسم و فامیلی برام جالب بود گفتم یه عرض ادبی بکنم
موفق باشی.
خانوما خیلی برنامه نویسای خوبی هستن...
من خودم یه نفر رو میشناسم که 1 ساله دات نت کار میکنه... هفته پیش روش اتصال به دیتابیس با SQLConnection رو کشف کرد.
نحوهی تعیین فرهنگ ترد جاری در ASP.NET Core
در نگارشهای پیشین ASP.NET، برای تعیین فرهنگ ترد جاری، از یکی از دو روش ذیل استفاده میشود:
الف) افزودن مدخل بومی سازی به فایل web.config
<system.web> <globalization uiCulture="fa-IR" culture="fa-IR" /> </system.web>
protected void Application_BeginRequest() { Thread.CurrentThread.CurrentCulture = new CultureInfo("fa-IR"); Thread.CurrentThread.CurrentUICulture = new CultureInfo("fa-IR"); }
public void Configure(IApplicationBuilder app) { app.UseRequestLocalization(new RequestLocalizationOptions { DefaultRequestCulture = new RequestCulture(new CultureInfo("fa-IR")), SupportedCultures = new[] { new CultureInfo("en-US"), new CultureInfo("fa-IR") }, SupportedUICultures = new[] { new CultureInfo("en-US"), new CultureInfo("fa-IR") } });
- تنظیمات SupportedCultures بر روی نمایش تاریخ، ساعت و واحد پولی تاثیر دارند. همچنین میتوانند بر روی نحوهی مقایسهی حروف و مرتب سازی آنها تاثیر داشته باشند.
- تنظیمات SupportedUICultures مشخص میکنند که کدامیک از فایلهای resx برنامه که مداخل ترجمههای آنرا به زبانهای مختلف مشخص میکنند، باید بارگذاری شوند.
- تنظیم DefaultRequestCulture در صورت مشخص نشدن فرهنگ ترد جاری مورد استفاده قرار میگیرد.
یک مثال: هر ترد در دات نت دارای اشیاء CurrentCulture و CurrentUICulture است. اگر فرهنگ ترد جاری به en-US تنظیم شده باشد، متد DateTime.Now.ToLongDateString، خروجی نمونه Thursday, February 18, 2016 را نمایش میدهد.
زمانیکه میان افزار RequestLocalization فعال میشود، سه تامین کنندهی پیش فرض (مقدارهای پیش فرض خاصیت RequestCultureProviders شیء RequestLocalizationOptions فوق)، جهت مشخص ساختن فرهنگ ترد جاری بکار گرفته خواهند شد:
الف) از طریق کوئری استرینگ با فعال سازی QueryStringRequestCultureProvider
http://localhost:5000/?culture=es-MX&ui-culture=es-MX
http://localhost:5000/?culture=es-MX
برای مثال در اینجا QueryStringRequestCultureProvider به دنبال کوئری استرینگهای culture و یا ui-culture گشته و با رسیدن به es-MX، فرهنگ جاری را به اسپانیایی مکزیکی تنظیم میکند. در این حالت اگر فقط culture ذکر شود، ui-culture نیز به همان مقدار تنظیم خواهد شد.
ب) از طریق نام کوکی با فعال سازی CookieRequestCultureProvider
CookieRequestCultureProvider کوکی ویژهای را با نام پیش فرض AspNetCore.Culture. ایجاد میکند. این کوکی برای ردیابی اطلاعات بومی سازی انتخابی کاربر بکار میرود. برای مثال اگر به مقدار ذیل تنظیم شود:
c='en-UK'|uic='en-US'
ج) از طریق هدر مخصوص Accept-Language با فعال سازی AcceptLanguageHeaderRequestCultureProvider که میتواند به همراه درخواست HTTP ارسال شود.
اگر تمام این حالتها تنظیم نشده بودند، آنگاه از مقدارDefaultRequestCulture استفاده میشود. برای مثال اگر مرورگر به صورت پیش فرض هدر Accept-Language را en-US ارسال میکند :
دیگر کار به پردازش مقدارDefaultRequestCulture نخواهد رسید.
اکنون اگر علاقمند بودید تا به کاربر امکان انتخاب زبانی را بدهید، یک چنین اکشن متدی را طراحی کنید:
public IActionResult SetFaLanguage() { Response.Cookies.Append( CookieRequestCultureProvider.DefaultCookieName, CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(new CultureInfo("fa-IR"))), new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) } ); return RedirectToAction("GetTitle"); }
از اینجا به بعد است که اگر نام کنترلر شما TestLocalController باشد، فایل منبع متناظر با آن یعنی Controllers.TestLocalController.fa.resx، به صورت خودکار بارگذاری و پردازش خواهد شد. در غیر اینصورت فایل نمونهی ختم شدهی به en.resx پردازش میشود؛ چون این زبان به صورت پیش فرض در هدر Accept-Language قید شدهاست.
آماده سازی برنامه برای کار با فایلهای منبع زبانهای مختلف
ابتدا پوشهی جدیدی را به نام Resources به ریشهی پروژه اضافه کنید. سپس به کلاس آغازین برنامه مراجعه کرده و محل یافت شدن این پوشه را معرفی کنید:
public void ConfigureServices(IServiceCollection services) { services.AddLocalization(options => options.ResourcesPath = "Resources"); services.AddMvc() .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix) .AddDataAnnotationsLocalization();
به علاوه به سرویس ASP.NET MVC، تنظیمات بومی سازی Viewها و DataAnnotations نیز اضافه شدهاند. تنظیم suffix به معنای view file suffix و یا مثلا fr در نام فایل Index.fr.cshtml است.
نحوهی تعریف و پوشه بندی فایلهای منبع زبانهای مختلف
تا اینجا پوشهی جدید Resources را به پروژه اضافه، معرفی و سرویسهای مرتبط را نیز فعال کردیم. پس از آن نوبت به افزودن فایلهای resx است. برای این منظور بر روی پوشهی منابع کلیک راست کرده و گزینهی add->new item را انتخاب کنید.
در اینجا با جستجوی resource، میتوان فایل resx جدیدی را به پروژه اضافه کرد؛ اما ... انتخاب نام آن باید بر اساس نکات ذیل باشد:
الف) برای کنترلرها یکی از دو مسیر / دار و یا نقطه دار جستجو میشوند:
Resources/Controllers.HomeController.fr.resx
Resources/Controllers/HomeController.fr.resx
در اینجا fr ذکر شده، همان LanguageViewLocationExpanderFormat.Suffix است که پیشتر بحث شد. قسمت ابتدایی Controllers همیشه ثابت است (یا به صورت نام یک پوشه و یا به عنوان قسمت اول نام فایل). سپس نام کلاس کنترلر به همراه نام فرهنگ مدنظر باید ذکر شوند. قسمت نام پوشهی Resources را نیز به services.AddLocalization معرفی کردهایم.
ب) برای Viewها نیز همان حالتهای / دار و یا نقطه دار بررسی میشوند:
Resources/Views.Home.About.fr.resx
Resources/Views/Home/About.fr.resx
برای تمام فایلها و کلاسها میتوان فایل منبع ایجاد کرد
در این نگارش از ASP.NET، در حالت کلی، نام یک فایل منبع، همان نام کامل کلاس آن است؛ منهای فضای نام آن (اگر این فایل منبع در همان اسمبلی قرار گیرد). برای مثال اگر میخواهید برای کلاس Startup برنامه، فایل منبعی را درست کنید و نام کامل آن با درنظر گرفتن فضای نام، معادل LocalizationWebsite.Web.Startup است، ابتدای فضای نام آنرا حذف کنید و سپس آنرا ختم به fa.resx کنید؛ مثلا Startup.fa.resx
اگر محل واقع شدن فایلهای resx در همان اسمبلی اصلی پروژه باشند، نیازی به ذکر فضای نام پیش فرض پروژه نیست. برای مثال اگر فضای نام پیش فرض پروژهی وب جاری MyLocalizationWebsite.Web است، بجای نام فایل MyLocalizationWebsite.Web.Controllers.HomeController.fr.resx میتوانید به صورت خلاصه بنویسید Controllers.HomeController.fr.resx. در غیراینصورت (استفاده از اسمبلیهای دیگر)، ذکر کامل فضای نام مرتبط هم الزامی است.
چند نکته:
- اگر ResourcesPath را در services.AddLocalization معرفی نکنید، مسیر پیش فرض یافتن فایلهای resx مربوط به کنترلرها، پوشهی ریشهی پروژه است و برای Viewها، همان پوشهی محل واقع شدن View متناظر خواهد بود.
- اینکه کدام فایل منبع در برنامه بارگذاری میشود، دقیقا مرتبط است با فرهنگ ترد جاری و این فرهنگ به صورت پیش فرض en-US است (چون همواره در هدر Accept-Language ارسالی توسط مرورگر وجود دارد). برای تغییر آن، از نکتهی اکشن متد public IActionResult SetFaLanguage ابتدای بحث استفاده کنید (در غیراینصورت در آزمایشات خود شاهد بارگذاری فایلهای منبع دیگری بجز en.resxها نخواهید بود).
- فایلهای منبع را به صورت کامپایل شده در پوشهی bin برنامه خواهید یافت:
خواندن اطلاعات منابع در کنترلرهای برنامه
فرض کنید کنترلری را به نام TestLocalController ایجاد کردهایم. بنابراین فایل منبع فارسی متناظر با آن Controllers.TestLocalController.fa.resx خواهد بود؛ با این محتوای نمونه:
محتوای این کنترلر نیز به صورت ذیل است:
using System; using System.Globalization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Localization; using Microsoft.Extensions.Localization; namespace Core1RtmEmptyTest.Controllers { public class TestLocalController : Controller { private readonly IStringLocalizer<TestLocalController> _stringLocalizer; private readonly IHtmlLocalizer<TestLocalController> _htmlLocalizer; public TestLocalController( IStringLocalizer<TestLocalController> stringLocalizer, IHtmlLocalizer<TestLocalController> htmlLocalizer) { _stringLocalizer = stringLocalizer; _htmlLocalizer = htmlLocalizer; } public IActionResult Index() { var name = "DNT"; var message = _htmlLocalizer["<b>Hello</b><i> {0}</i>", name]; ViewData["Message"] = message; return View(); } [HttpGet] public string GetTitle() { var about = _stringLocalizer["About Title"]; return about; } public IActionResult SetFaLanguage() { Response.Cookies.Append( CookieRequestCultureProvider.DefaultCookieName, CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(new CultureInfo("fa-IR"))), new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) } ); return RedirectToAction("GetTitle"); } } }
اگر برنامه را در حالت معمولی اجرا کنید و سپس آدرس http://localhost:7742/testlocal/gettitle را درخواست کنید، عبارت About Title را مشاهده میکنید؛ به دو علت:
الف) هنوز فرهنگ پیش فرض ترد جاری همان en-US است که توسط مرورگر ارسال شدهاست.
ب) چون فایل resx متناظر با فرهنگ پیش فرض ترد جاری یافت نشدهاست، مقدار همان کلید درخواستی بازگشت داده میشود؛ یعنی همان About Title.
برای رفع این مشکل آدرس http://localhost:7742/testlocal/SetFaLanguage را درخواست کنید. به این صورت با تنظیم کوکی ردیابی فرهنگ ترد جاری به زبان فارسی، خروجی GetTile اینبار «درباره» خواهد بود.
خواندن اطلاعات منابع در Viewهای برنامه
فرض کنید فایل Views.TestLocal.Index.fa.resx (فایل منبع کنترلر TestLocal و ویوو Index آن به زبان فارسی) دقیقا همان محتوای فایل Controllers.TestLocalController.fa.resx فوق را دارد (اگر نام پوشهی Views را تغییر دادهاید، قسمت ابتدایی نام فایل Views را هم باید تغییر دهید). برای دسترسی به اطلاعات آن در یک ویوو، میتوان از سرویس IViewLocalizer به نحو ذیل استفاده کرد:
@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer @{ } Message @ViewData["Message"] <br/> @Localizer["<b>Hello</b><i> {0}</i>", "DNT"] <br/> @Localizer["About Title"]
Localizer از طریق تزریق سرویس IViewLocalizer به View برنامه تامین میشود. این سرویس در پشت صحنه از همان IHtmlLocalizer استفاده میکند و در حین استفادهی از آن، اطلاعات تگها انکد (encoded) نخواهند شد (به همین جهت برای کار با کلیدها و مقادیر تگدار توصیه میشود).
استفاده از اطلاعات منابع در DataAnnotations
قسمت اول فعال سازی بومی سازی DataAnnotations با ذکر AddDataAnnotationsLocalization در متد ConfigureServices، در ابتدای بحث انجام شد و همانطور که پیشتر نیز عنوان گردید، در این نگارش از ASP.NET، برای تمام کلاسهای برنامه میتوان فایل منبع ایجاد کرد. برای مثال اگر کلاس RegisterViewModel در فضای نام ViewModels.Account قرار گرفتهاست، نام فایل منبع آن یکی از دو حالت / دار و یا نقطه دار ذیل میتواند باشد:
Resources/ViewModels.Account.RegisterViewModel.fr.resx
Resources/ViewModels/Account/RegisterViewModel.fr.resx
محتوای این کلاس را در ذیل مشاهده میکنید:
using System.ComponentModel.DataAnnotations; namespace Core1RtmEmptyTest.ViewModels.Account { public class RegisterViewModel { [Required(ErrorMessage = "EmailReq")] [EmailAddress(ErrorMessage = "EmailType")] [Display(Name = "Email")] public string Email { get; set; } } }
یک نکته: هیچ الزامی ندارد که کلیدها را به این شکل وارد کنید. از این جهت که اگر این کلید در فایل منبع یافت نشد و یا فرهنگ ترد جاری با فایلهای منبع مهیا تطابقی نداشت، عبارتی را که کاربر مشاهده میکند، دقیقا معادل «EmailReq» خواهد بود. بنابراین در اینجا میتوانید کلید را به صورت کامل، مثلا مساوی «The Email field is required» وارد کنید و همین عبارت را به عنوان کلید در فایل منبع ذکر کرده و مقدار آنرا مساوی ترجمهی آن قرار دهید. این نکته در تمام حالات کار با کنترلرها و ویووها نیز صادق است.
استفاده از یک منبع اشتراکی
اگر میخواهید تعدادی از منابع را در همهجا در اختیار داشته باشید، روش کار به این صورت است:
الف) یک کلاس خالی را به نام SharedResource دقیقا با فرمت ذیل در پوشهی Resources ایجاد کنید:
// Dummy class to group shared resources namespace Core1RtmEmptyTest { public class SharedResource { } }
SharedResource.fa.resx
SharedResource.en-US.resx
و امثال آن
ج) برای استفادهی از این منبع اشتراکی در کلاسهای مختلف برنامه تنها کافی است در حین تزریق وابستگیها، نوع آرگومان جنریک IStringLocalizer را به SharedResource تنظیم کنید:
IStringLocalizer<SharedResource> sharedLocalizer
@inject IHtmlLocalizer<SharedResource> SharedLocalizer
Come learn the top 7 reasons to use Visual Studio 2017 if you are a C++ developer. Whether you are using the product and are looking to upgrade, or you never used it before but you are considering it now, join us to discover how Visual Studio 2017 raises the bar in terms of C++ productivity. From C++ standards conformance to coding productivity, cross-platform development for Windows, Linux, Android, and iOS and CMake support, these are only a few of the topics we discuss in this demo-packed session.
حلقه های تکرار
انواع حلقههای تکرار
- حلقه تکرار for in
- حلقه تکرار for to
- حلقه تکرار while do
در ادامه به بررسی و پیاده سازی مثال برای هر سه حلقه میپردازیم
#1 حلقه for سادهlet list1 = [ 1; 5; 100; 450; 788 ] for i in list1 do printfn "%d" i
1 5 100 450 788
for i in 1 .. 2 .. 10 do printf "%d " i
1 3 5 7 9
for c in 'a' .. 'z' do printf "%c " c
a b c d e f g h i j k l m n o p q r s t u v w x y z
for i in 10 .. -1 .. 1 do printf "%d " i
10 9 8 7 6 5 4 3 2 1
let beginning x y = x - 2*y let ending x y = x + 2*y for i in (beginning x y) .. (ending x y) do printf "%d " i
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
for i = 1 to 10 do printf "%d " i
1 2 3 4 5 6 7 8 9 10
for i = 10 downto 1 do printf "%d " i
10 9 8 7 6 5 4 3 2 1
for i = (beginning x y) to (ending x y) do printf "%d " i
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#9 حلقه while do
ساختار کلی آن به صورت زیر است.
while test-expression do body-expression
open System let main() = let password = "monkey"//شناسه برای مقدار رمز عبور let mutable guess = String.Empty// شناسه برای حدس رمز عبور let mutable attempts = 0//تعداد دفعات تست while password <> guess && attempts < 3 do// تا زمانی که رمز عبور با حدس آن برابر نیست و تعداد دفعات تکرار کمتر از سه است Console.Write("What's the password? ")//چاپ پیغام در خروجی attempts <- attempts + 1//مقدار دفعات یکی افزایش مییابد guess <- Console.ReadLine()// حدس رمز عبور از ورودی دریافت میشود if password = guess then// اگر رمز عبور با حدس آن یکی بود Console.WriteLine("You got the password right!")// پیغام موفقیت else Console.WriteLine("You didn't guess the password")//پیغام عدم موفقیت Console.ReadKey(true) |> ignore//منتظر ورودی برای خروج از برنامه
دورهی کامل میکروسرویسها در دات نت
.NET Microservices – Full Course, Les Jackson
In this step-by-step tutorial I take you through an introduction on building microservices using .NET. As the name suggests we build everything completely from start to finish –with the full scope of the course outlined in the time-stamp section below. However, at a high-level we’ll cover:
• Building two .NET Microservices using the REST API pattern
• Working with dedicated persistence layers for both services
• Deploying our services to Kubernetes cluster
• Employing the API Gateway pattern to route to our services
• Building Synchronous messaging between services (HTTP & gRPC)
• Building Asynchronous messaging between services using an Event Bus (RabbitMQ)