- ctrl+shift+p را فشرده و Setting را جستجو نمایید .
- در کادر باز شده User Settings را انتخاب کرده تا در چپ تنظیمات پیش فرض و در سمت راست تنظیمات کاربر نمایش داده شود.
- از لیست موجود Git را باز نمایید
- در صورتی که مقدار "git.path" برابر با null بود ، از منوی سمت راست آن را با مسیر مناسب مثلا "D:\\Programs\\Git\\bin\\git.exe " جایگزین نمایید .
- VSCode را ری استارت کنید.
معرفی NET MAUI Preview 4.
Today we are pleased to announce the availability of .NET Multi-platform App UI (.NET MAUI) Preview 4. Each preview introduces more controls and features to this multi-platform toolkit on our way to general availability this November at .NET Conf. .NET MAUI now has enough building blocks to build functional applications for all supported platforms, new capabilities to support running Blazor on the desktop, and exciting progress in Visual Studio to support .NET MAUI.
*در دنیای NoSql پیاده سازیهای متفاوتی از دیتابیسها انجام شده است و هر دیتابیس، ویژگیها و مزایا و معایب خاص خودش را دارد. باید قبول کرد که همیشه و همه جا نمیتوان از یک پایگاه داده NoSql مشخص استفاده نماییم (دلایلی نظیر محدودیتهای License، هزینه پیاده سازی و...). در نتیجه بررسی یک دیتابیس دیگر با شرایط و توانمندیهای خاص آن خالی از سود نیست.
» این دیتاییس در گروه Graph databasesها قرار دارد و از زبان SPARQL (بخوانید Sparkle) برای کوئری گرفتن و کار با دادهها بهره میبرد؛
» متن باز و رایگان است
» پشتیبانی از دات نت چهار به بعد؛
» قابل استفاده در Mobile Application - Windows phone 7 , 8؛
» بدون شما (Schema Less) و با قابیلت ذخیره سازی triple و به فرمت RDF
» پشتیبانی از Linq و OData؛
» پشتیبانی از تراکنشها ؛
» پیاده سازی مدل برنامه به صورت Code First؛
» سرعت بالا جهت ذخیره سازی و لود اطلاعات؛
» نیاز به پیکربندیهای خاص جهت پیاده سازی ندارد؛
» ارائه افزونه رایگان Polaris جهت کوئری گفتن و نمایش Visual داده ها.
و غیره که در ادامه با آنها آشنا خواهید شد.
در B*Db دو روش برای ذخیره سازی اطلاعات وجود دارد:
» Append Only : در این روش تمامی تغییرات (عملیات نوشتن) در انتهای فایل index اضافه خواهد شد. این روش مزایای زیر را به دنبال خواهد داشت:
- عملیات نوشتن هیچگاه عملیات خواندن اطلاعات را block نمیکند. در
نتیجه هر تعداد عملیات خواندن فایل (منظور اجرای کوئریهای SPQRL است) میتواند به صورت موازی بر روی Storeها اجرا شود.
- به دلیل اینکه عمل ویرایش واقعی هیچ گاه انجام نمیشود (دادهها فقط اضافه خواهند شد) همیشه میتوانید وضعیت Store را به حالتهای قبلی بازگردانید.
- عملیات نوشتن اطلاعات بسیار سریع خواهد بود.
نکته ای که باید به آن دقت داشت این است که فقط در هنگام ساخت Storeها میتوانید نوع ذخیره سازی آن را تعیین نمایید، بعد از ساخت Store امکان سوئیچ بین حالات امکان پذیر نیست.
همان طور که پیشتر گفته شد B*Db برای ذخیره سازی اطلاعات از سند RDF بهره میبرد. البته با RDF Syntaxهای متفاوت :
هم چنین در B*Db چهار روش برای دست یابی با دادهها (پیاده سازی عملیات CRUD) وجود دارد از قبیل:
» B*Db EntityFramewok
» Data Object Layer
» RDF Client Api
» Dynamic API
که هر کدام در طی پستهای متفاوت بررسی خواهد شد.
بررسی یک مثال با روش B*Db EntityFramework
برای شروع ابتدا یک پروژه جدید از نوع Console Application ایجاد کنید. سپس از طریق Nuget اقدام به نصب Package زیر نمایید:
pm> install-Package BirghtStarDb
PM> Install-Package BirghtStarDbLibs
بعد از نصب پکیجهای بالا یک فایل Text Template با نام MyEntityContext.tt نیز به پروژه افزوده خواهد شد. این فایل جهت تولید خودکار مدلهای برنامه استفاده میشود. اما برای این کار لازم است به ازای هر مدل ابتدا یک اینترفیس ایجاد نمایید. برای مثال:
[Entity] public interface IBook { public int Code { get; set; } public string Title { get; set; } }
» نیاز به ایجاد یک خاصیت به عنوان Id وجود ندارد. به صورت پیش فرض خاصیت Id با نوع string برای هر مدل پیاده سازی میشود. اما اگر قصد دارید این نام خاصیت را تغییر دهید میتوانید به صورت زیر عمل کنید:
[Entity] public interface IBook { [Identifier] public string MyId { get; } public int Code { get; set; } public string Title { get; set; } }
استفاده از اینترفیس برای ساخت مدل انعطاف پذیری بالایی را در اختیار ما قرار میدهد که بعدا مفصل بحث خواهد شد. برای عملیات درج داده میتوان به صورت زیر عمل کنید:
MyEntityContext context = new MyEntityContext("type=embedded;storesdirectory=c:\brightstar;storename=test"); var book = context.Books.Create(); book.Code = 1; book.Title = "Test"; context.Books.Add(book); context.SaveChanges();
»embedded : در این حالت از طریق آدرس فیزیکی فایل مورد نظر میتوان یک Connection ایجاد کرد.
»rest : یا استفاده از HTTP یا HTTPS میتوان به سرویس B*Db دسترسی داشت.
»dotNetRdf : برای ارتباط با یک Store دیگر با استفاده از اتصال دهندههای DotNetRDf.
»sparql : اتصال به منبع داده ای دیگر با استفاده از پروتکل SPARQL
در هنگام ایجاد اتصال باید نوع مورد نظر را از حتما تعیین نمایید. با استفاده از storedirctory مکان فیزیکی فایل تعیین خواهد شد.
بررسی کردن مجوزهای مخازن GitHub
Designed natively for the Mac
Visual Studio for Mac brings the developer productivity you love to the Mac. The experience has been meticulously crafted to optimize the developer workflow for the Mac.
Collaborate efficiently
Manage your code in Git repos, hosted by any provider, including GitHub and Visual Studio Team Services. Share projects seamlessly with developers using Visual Studio across Windows and Mac.
1.30 Visual Studio Code منتشر شد
Welcome to the November 2018 release of Visual Studio Code. There are a number of significant updates in this version that we hope you will like, some of the key highlights include:
- Multiline search improvements - Easily create multiline search patterns without using regex.
- Custom title bar on Linux - The custom title and menu bar is now the default on Linux.
- References view - Find All References view includes history of recent searches.
- Snippet comment variables - Snippet variables insert correct comment per language.
- JS/TS callback display - Now you can see the context of anonymous callbacks.
- JSDoc Markdown highlighting - Including syntax highlighting for Markdown code blocks in JSDoc.
- Simplified debug configuration - Better defaults and Quick Pick UI for initial launch configuration.
- Run tasks on folder open - Configure tasks to run when you first open a project folder.
- Choose extension version - Install earlier versions of Marketplace extensions.
مجوز استفاده از فایلهای جاوا اسکریپتی آن MIT است؛ به این معنا که در هر نوع پروژهای قابل استفاده است. مجوز استفاده از کامپوننتهای سمت سرور آن که برای نمونه جهت ASP.NET MVC یک سری HTML Helper را تدارک دیدهاند، تجاری میباشد. در ادامه قصد داریم صرفا از فایلهای JS عمومی آن استفاده کنیم.
دریافت jqGrid
برای دریافت jqGrid میتوانید به مخزن کد آن، در آدرس https://github.com/tonytomov/jqGrid/releases و یا از طریق NuGet اقدام کنید:
PM> Install-Package Trirand.jqGrid
از jQuery UI برای تولید صفحات جستجوی بر روی رکوردها و همچنین تولید خودکار صفحات ویرایش و یا افزودن رکوردها استفاده میکند. به علاوه آیکنها، قالب و رنگ خود را نیز از jQuery UI دریافت میکند. بنابراین اگر قصد تغییر قالب آنرا داشتید تنها کافی است یک قالب استاندارد دیگر jQuery UI را مورد استفاده قرار دهید.
تنظیمات اولیه فایل Layout سایت
پس از دریافت بستهی نیوگت jqGrid، نیاز است فایلهای مورد نیاز اصلی آنرا به شکل زیر به فایل layout پروژه اضافه کرد:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - My ASP.NET Application</title> <link href="~/Content/themes/base/jquery.ui.all.css" rel="stylesheet" /> <link href="~/Content/jquery.jqGrid/ui.jqgrid.css" rel="stylesheet" /> <link href="~/Content/Site.css" rel="stylesheet" type="text/css" /> </head> <body> <div> @RenderBody() </div> <script src="~/Scripts/jquery-1.7.2.min.js"></script> <script src="~/Scripts/jquery-ui-1.8.11.min.js"></script> <script src="~/Scripts/i18n/grid.locale-fa.js"></script> <script src="~/Scripts/jquery.jqGrid.min.js"></script> @RenderSection("Scripts", required: false) </body> </html>
این گرید به همراه فایل زبان فارسی grid.locale-fa.js نیز میباشد که در کدهای فوق پیوست شدهاست. البته اگر فرصت کردید نیاز است کمی ترجمههای آن بهبود پیدا کنند.
تنظیمات ثانویه site.css
.ui-widget { } /*how to move jQuery dialog close (X) button from right to left*/ .ui-jqgrid .ui-jqgrid-caption-rtl { text-align: center !important; } .ui-dialog .ui-dialog-titlebar-close { left: .3em !important; } .ui-dialog .ui-dialog-title { margin: .1em 0 .1em .8em !important; direction: rtl !important; float: right !important; }
همچنین محل قرار گیری دکمهی بسته شدن دیالوگها و راست به چپ کردن عناوین آنها نیز در اینجا قید شدهاند.
مدل برنامه
در ادامه قصد داریم لیستی از محصولات را با ساختار ذیل، توسط jqGrid نمایش دهیم:
namespace jqGrid01.Models { public class Product { public int Id { set; get; } public string Name { set; get; } public decimal Price { set; get; } public bool IsAvailable { set; get; } } }
ساختار دادهای مورد نیاز توسط jqGrid
jqGrid مستقل است از فناوری سمت سرور. بنابراین هر چند در عنوان بحث ASP.NET MVC ذکر شدهاست، اما از ASP.NET MVC صرفا جهت بازگرداندن خروجی JSON استفاده خواهیم کرد و این مورد در هر فناوری سمت سرور دیگری نیز میتواند انجام شود.
using System.Collections.Generic; namespace jqGrid01.Models { public class JqGridData { public int Total { get; set; } public int Page { get; set; } public int Records { get; set; } public IList<JqGridRowData> Rows { get; set; } public object UserData { get; set; } } public class JqGridRowData { public int Id { set; get; } public IList<string> RowCells { set; get; } } }
Total، نمایانگر تعداد صفحات اطلاعات است. عدد Page، شماره صفحهی جاری است. عدد Records، تعداد کل رکوردهای گزارش را مشخص میکند. ساختار ردیفهای آن نیز تشکیل شدهاست از یک Id به همراه سلولهایی که باید با فرمت string، بازگشت داده شوند.
UserData اختیاری است. برای مثال اگر خواستید جمع کل صفحه را در ذیل گرید نمایش دهید، میتوانید یک anonymous object را در اینجا مقدار دهی کنید. خاصیتهای آن دقیقا باید با نام خاصیتهای ستونهای متناظر، یکی باشند. برای مثال اگر میخواهید عددی را در ستون Id، در فوتر گرید نمایش دهید، باید نام خاصیت را Id ذکر کنید.
کدهای سمت کلاینت گرید
در اینجا کدهای کامل سمت کلاینت گرید را ملاحظه میکنید:
@{ ViewBag.Title = "Index"; } <div dir="rtl" align="center"> <div id="rsperror"></div> <table id="list" cellpadding="0" cellspacing="0"></table> <div id="pager" style="text-align:center;"></div> </div> @section Scripts { <script type="text/javascript"> $(document).ready(function () { $('#list').jqGrid({ caption: "آزمایش اول", //url from wich data should be requested url: '@Url.Action("GetProducts","Home")', //type of data datatype: 'json', jsonReader: { root: "Rows", page: "Page", total: "Total", records: "Records", repeatitems: true, userdata: "UserData", id: "Id", cell: "RowCells" }, //url access method type mtype: 'GET', //columns names colNames: ['شماره', 'نام محصول', 'موجود است', 'قیمت'], //columns model colModel: [ { name: 'Id', index: 'Id', align: 'right', width: 50, sorttype: "number" }, { name: 'Name', index: 'Name', align: 'right', width: 300 }, { name: 'IsAvailable', index: 'IsAvailable', align: 'center', width: 100, formatter: 'checkbox' }, { name: 'Price', index: 'Price', align: 'center', width: 100, sorttype: "number" } ], //pager for grid pager: $('#pager'), //number of rows per page rowNum: 10, rowList: [10, 20, 50, 100], //initial sorting column sortname: 'Id', //initial sorting direction sortorder: 'asc', //we want to display total records count viewrecords: true, altRows: true, shrinkToFit: true, width: 'auto', height: 'auto', hidegrid: false, direction: "rtl", gridview: true, rownumbers: true, footerrow: true, userDataOnFooter: true, loadComplete: function() { //change alternate rows color $("tr.jqgrow:odd").css("background", "#E0E0E0"); }, loadError: function(xhr, st, err) { jQuery("#rsperror").html("Type: " + st + "; Response: " + xhr.status + " " + xhr.statusText); } //, loadonce: true }) .jqGrid('navGrid', "#pager", { edit: false, add: false, del: false, search: false, refresh: true }) .jqGrid('navButtonAdd', '#pager', { caption: "تنظیم نمایش ستونها", title: "Reorder Columns", onClickButton: function() { jQuery("#list").jqGrid('columnChooser'); } }); }); </script> }
Div سومی با id مساوی rsperror نیز تعریف شدهاست که از آن جهت نمایش خطاهای بازگشت داده شده از سرور استفاده کردهایم.
- در ادامه نحوهی فراخوانی افزونهی jqGrid را بر روی جدول list ملاحظه میکنید.
- خاصیت caption، عنوان نمایش داده شده در بالای گرید را مقدار دهی میکند:
- خاصیت url، به آدرسی اشاره میکند که قرار است ساختار JqGridData ایی را که پیشتر در مورد آن بحث کردیم، با فرمت JSON بازگشت دهد. در اینجا برای مثال به یک اکشن متد کنترلری در یک پروژهی ASP.NET MVC اشاره میکند.
- datatype را برابر json قرار دادهایم. از نوع xml نیز پشتیبانی میکند.
- شیء jsonReader را از این جهت مقدار دهی کردهایم تا بتوانیم شیء JqGridData را با اصول نامگذاری دات نت، هماهنگ کنیم. برای درک بهتر این موضوع، فایل jquery.jqGrid.src.js را باز کنید و در آن به دنبال تعریف jsonReader بگردید. به یک چنین مقادیر پیش فرضی خواهید رسید:
ts.p.jsonReader = $.extend(true,{ root: "rows", page: "page", total: "total", records: "records", repeatitems: true, cell: "cell", id: "id", userdata: "userdata", subgrid: {root:"rows", repeatitems: true, cell:"cell"} },ts.p.jsonReader);
- در ادامه mtype به GET تنظیم شدهاست. در اینجا مشخص میکنیم که عملیات Ajax ایی دریافت اطلاعات از سرور توسط GET انجام شود یا برای مثال توسط POST.
- خاصیت colNames، معرف نام ستونهای گرید است. برای اینکه این نامها از راست به چپ نمایش داده شوند، باید خاصیت direction به rtl تنظیم شود.
- colModel آرایهای است که تعاریف ستونها را در بر دارد. مقدار name آن باید یک نام منحصربفرد باشد. از این نام در حین جستجو یا ویرایش اطلاعات استفاده میشود. مقدار index نامی است که جهت مرتب سازی اطلاعات، به سرور ارسال میشود. تنظیم sorttype در اینجا مشخص میکند که آیا به صورت پیش فرض، ستون جاری رشتهای مرتب شود یا اینکه برای مثال عددی پردازش گردد. مقادیر مجاز آن text (مقدار پیش فرض)، float، number، currency، numeric، int ، integer، date و datetime هستند.
- در ستون IsAvailable، مقدار formatter نیز تنظیم شدهاست. در اینجا توسط formatter، نوع bool دریافتی با یک checkbox نمایش داده خواهد شد.
- خاصیت pager به id متناظری در صفحه اشاره میکند.
- توسط rowNum مشخص میکنیم که در هر صفحه چه تعداد رکورد باید نمایش داده شوند.
- تعداد رکوردهای نمایش داده شده را میتوان توسط rowList پویا کرد. در اینجا آرایهای را ملاحظه میکنید که توسط اعداد آن، کاربر امکان انتخاب صفحاتی مثلا 100 ردیفه را نیز پیدا میکند. rowList به صورت یک dropdown در کنار عناصر راهبری صفحه در فوتر گرید ظاهر میشود.
- خاصیت sortname، نحوهی مرتب سازی اولیه گرید را مشخص میکند.
- خاصیت sortorder، جهت مرتب سازی اولیهی گردید را تنظیم میکند.
- viewrecords: تعداد رکوردها را در نوار ابزار پایین گرید نمایش میدهد.
- altRows: سبب میشود رنگ متن ردیفها یک در میان متفاوت باشد.
- shrinkToFit: به معنای تنظیم خودکار اندازهی سلولها بر اساس اندازهی دادهای است که دریافت میکنند.
- width: عرض گرید، که در اینجا به auto تنظیم شدهاست.
- height: طول گرید، که در اینجا به auto جهت محاسبهی خودکار، تنظیم شدهاست.
- gridview: برای بالا بردن سرعت نمایشی به true تنظیم شدهاست. در این حالت کل ردیف یکباره درج میشود. اگر از subgird یا حالت نمایش درختی استفاده شود، باید این خاصیت را false کرد.
- rownumbers: ستون سمت راست شماره ردیفهای خودکار را نمایش میدهد.
- footerrow: سبب نمایش ردیف فوتر میشود.
- userDataOnFooter: سبب خواهد شد تا خاصیت UserData مقدار دهی شده، در ردیف فوتر ظاهر شود.
- loadComplete : یک callback است که زمان پایان بارگذاری صفحهی جاری را مشخص میکند. در اینجا با استفاده از jQuery سبب شدهایم تا رنگ پس زمینهی ردیفها یک در میان تغییر کند.
- loadError: اگر از سمت سرور خطایی صادر شود، در این callback قابل دریافت خواهد بود.
- در ادامه توسط فراخوانی متد jqGrid با پارامتر navGrid، در ناحیه pager سبب نمایش دکمه refresh شدهایم. این دکمه سبب بارگذاری مجدد اطلاعات گردید از سرور میشود.
- همچنین به کمک متد jqGrid با پارامتر navButtonAdd در ناحیه pager، سبب نمایش دکمهای که صفحهی انتخاب ستونها را ظاهر میکند، خواهیم شد.
پیشنیاز کدهای سمت سرور jqGrid
اگر به تنظیمات گرید دقت کرده باشید، خاصیت index ستونها، نامی است که به سرور، جهت اطلاع رسانی در مورد فیلتر اطلاعات و مرتب سازی مجدد آنها ارسال میگردد. این نام، بر اساس کلیک کاربر بر روی ستونهای موجود، هر بار میتوان متفاوت باشد. بنابراین بجای if و else نوشتنهای طولانی جهت مرتب سازی اطلاعات، میتوان از کتابخانهی معروفی به نام dynamic LINQ استفاده کرد.
PM> Install-Package DynamicQuery
کدهای سمت سرور بازگشت اطلاعات به فرمت JSON
در کدهای سمت کلاینت، به اکشن متد GetProducts اشاره شده بود. تعاریف کامل آنرا در ذیل مشاهده میکنید:
using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Web.Mvc; using jqGrid01.Models; using jqGrid01.Extensions; // for dynamic OrderBy namespace jqGrid01.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(); } public ActionResult GetProducts(string sidx, string sord, int page, int rows) { var list = ProductDataSource.LatestProducts; var pageIndex = page - 1; var pageSize = rows; var totalRecords = list.Count; var totalPages = (int)Math.Ceiling(totalRecords / (float)pageSize); var products = list.AsQueryable() .OrderBy(sidx + " " + sord) .Skip(pageIndex * pageSize) .Take(pageSize) .ToList(); var jqGridData = new JqGridData { UserData = new // نمایش در فوتر { Name = "جمع صفحه", Price = products.Sum(x => x.Price) }, Total = totalPages, Page = page, Records = totalRecords, Rows = (products.Select(product => new JqGridRowData { Id = product.Id, RowCells = new List<string> { product.Id.ToString(CultureInfo.InvariantCulture), product.Name, product.IsAvailable.ToString(), product.Price.ToString(CultureInfo.InvariantCulture) } })).ToList() }; return Json(jqGridData, JsonRequestBehavior.AllowGet); } } }
- امضای متد GetProducts نیز مهم است. دقیقا همین پارامترها با همین نامها از طرف jqGrid به سرور ارسال میشوند که توسط آنها ستون مرتب سازی، جهت مرتب سازی، صفحهی جاری و تعداد ردیفی که باید بازگشت داده شوند، قابل دریافت است.
- در این کدها دو قسمت مهم وجود دارند:
الف) متد OrderBy نوشته شده، به صورت پویا عمل میکند و از کتابخانهی Dynamic LINQ مایکروسافت بهره میبرد.
به علاوه توسط Take و Skip کار صفحه بندی و بازگشت تنها بازهای از اطلاعات مورد نیاز، انجام میشود.
ب) لیست جنریک محصولات، در نهایت باید با فرمت JqGridData به صورت JSON بازگشت داده شود. نحوهی این Projection را در اینجا میتوانید ملاحظه کنید.
هر ردیف این لیست، باید تبدیل شود به ردیفی از جنس JqGridRowData، تا توسط jqGrid قابل پردازش گردد.
- توسط مقدار دهی UserData، برچسبی را در ذیل ستون Name و مقداری را در ذیل ستون Price نمایش خواهیم داد.
برای مطالعهی بیشتر
بهترین راهنمای جزئیات این Grid، مستندات آنلاین آن هستند: http://www.trirand.com/jqgridwiki/doku.php?id=wiki:jqgriddocs
همچنین این مستندات را با فرمت PDF نیز میتوانید مطالعه کنید: http://www.trirand.com/blog/jqgrid/downloads/jqgriddocs.pdf
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید
jqGrid01.zip
مثالهای سری jqGrid تغییرات زیادی داشتند. برای دریافت آنها به این مخزن کد مراجعه کنید.
تولید خودکار کدها بر اساس OpenAPI Specification
فرض کنید در حال توسعهی برنامهی سمت کلاینت Angular و یا سمت سرور ASP.NET Core ای هستید که هر دوی اینها از یک Web API استفاده میکنند. همچنین فرض کنید که این Web API را نیز خودتان توسعه میدهید. بنابراین حداقل کدی که باید در اینجا به اشتراک گذاشته شود، کدهای کلاسهای DTO یا Data transfer objects هستند تا این کلاینتها بتوانند اطلاعات Web API را به نحو صحیحی Deserialize کنند و یا برعکس، بتوانند اطلاعات را با فرمت صحیحی به سمت Web API ارسال کنند.
برای مدیریت این مساله میتوان از دو روش استفاده کرد:
الف) استفاده از یک پروژهی اشتراکی
اگر کدهای مدنظر، سمت سرور باشند، میتوان یک پروژهی اشتراکی را برای این منظور ایجاد کرد و کدهای DTO را درون آن قرار داد و سپس ارجاعی به آن را در پروژههای مختلف، استفاده نمود. به این ترتیب تکرار کدها، کاهش یافته و همچنین تغییرات آن نیز به تمام پروژههای استفاده کننده به نحو یکسانی اعمال میشوند. در این حالت یک اسمبلی اشتراکی تولید شده و به صورت مستقلی توزیع میشود.
ب) استفاده از روش لینک کردن فایلها
در این روش پروژههای استفاده کننده از کلاسهای DTO، فایلهای آنرا به پروژهی خود لینک میکنند. در این حالت باز هم شاهد کاهش تکرار کدها و همچنین اعمال یک دست تغییرات خواهیم بود. اما در این روش دیگر یک اسمبلی اشتراکی وجود نداشته و کلاسهای DTO هم اکنون با اسمبلی پروژههای استفاده کننده، یکی و کامپایل شدهاند.
بدیهی است در هر دو روش، نیاز است بر روی کلاینت و API، کنترل کاملی وجود داشته باشد و بتوان به کدهای آنها دسترسی داشت. به علاوه فایلهای اشتراکی نیز باید بر اساس Target platform یکسانی تولید شده باشند. در این حالت دیگر نیازی به OpenAPI Specification برای تولید کدهای کلاینت دات نتی خود، نیست.
اما اگر کدهای API مدنظر در دسترس نباشند و یا بر اساس پلتفرم دیگری مانند node.js تولید شده باشد، کار یکپارچه سازی با آن دیگر با به اشتراک گذاری فایلهای آن میسر نیست. در این حالت اگر این API به همراه یک OpenAPI Specification باشد، میتوان از آن برای تولید خودکار کدهای کلاینتهای آن استفاده کرد.
معرفی تعدادی از ابزارهایی که قادرند بر اساس OpenAPI Specification، کد تولید کنند
برای تولید کد از روی OpenAPI Specification، گزینههای متعددی در دسترس هستند:
الف) Swagger CodeGen
این ابزار را که جزئی از مجموعه ابزارهای تولید شدهی برفراز OpenAPI است، میتوانید از آدرس swagger-codegen دریافت کنید. البته برای اجرای آن نیاز به Java Runtime است و یا نگارش آنلاین آن نیز در دسترس است: swagger.io
در ابزار آنلاین آن، در منوی generate بالای صفحه، گزینهی تولید کد برای #C نیز موجود است.
ب) AutoRest
محل دریافت: https://github.com/Azure/autorest
بر اساس node.js کار میکند و از طریق خط فرمان، قابل دسترسی است. همچنین این مورد ابزار تامین کنندهی گزینهی Add REST client در ویژوال استودیو نیز میباشد. اما در کل، امکان تنظیمات آنچنانی را به همراه ندارد.
ج) NSwagStudio
محل دریافت: https://github.com/RSuter/NSwag/wiki/NSwagStudio
همانطور که در مطلب «مستند سازی ASP.NET Core 2x API توسط OpenAPI Swagger - قسمت اول - معرفی» نیز عنوان شد، NSwag یکی دیگر از تولید کنندههای OpenAPI Specification مخصوص پروژههای دات نت است. NSwagStudio نیز جزئی از این مجموعه است که به کمک آن میتوان کدهای کلاینتها و DTOها را بر اساس OpenAPI Spec تولید کرد. همچنین امکان تنظیمات قابل توجهی را در مورد نحوهی تولید کدهای نهایی به همراه دارد.
استفاده از NSwagStudio برای تولید کدهای DTOها
در اینجا از همان برنامهای که در سری «مستند سازی ASP.NET Core 2x API توسط OpenAPI Swagger» بررسی کردیم، استفاده خواهیم کرد. بنابراین این برنامه، از پیش تنظیم شدهاست و هم اکنون به همراه یک تولید کنندهی OpenAPI Specification نیز میباشد. آنرا اجرا کنید تا بتوان به OpenAPI Specification تولیدی آن در آدرس زیر دسترسی یافت:
https://localhost:5001/swagger/LibraryOpenAPISpecification/swagger.json
مطابق تصویر، ابتدا آدرس Swagger Specification URL یا همان آدرس فوق را وارد کنید. سپس فضای نام دلخواهی را وارد کرده و گزینهی تولید کلاسهای کلاینت را فعلا انتخاب نکنید. در لیست تنظیمات آن، گزینهی Class Style نیز مهم است. برای مثال برای پروژههای ASP.NET Core حالت POCO را انتخاب کنید (plain old clr objects) و برای پروژههای مبتنی بر XAML، گزینهی Inpc مناسبتر است چون RaisePropertyChangedها را هم تولید میکند. در آخر بر روی دکمهی Generate Outputs کلیک کنید تا خروجی ذیل حاصل شود:
یا میتوان این خروجی را copy/paste کرد و یا میتوان در برگهی Settings، در انتهای لیست آن، مقدار output file path را مشخص کرد و سپس بر روی دکمهی Generate files کلیک نمود تا فایل معادل آن تولید شود.
استفاده از NSwagStudio برای تولید کدهای کلاینت Angular استفاده کنندهی از API
NSwagStudio امکان تولید یک TypeScript Client را نیز دارد:
در اینجا ابتدا TypeScript Client را انتخاب میکنیم و سپس در تنظیمات آن، قالب Angular را انتخاب کرده و نگارش RxJS آنرا نیز، 6 انتخاب میکنیم. در آخر بر روی Generate outputs کلیک میکنیم:
نکتهی جالب این خروجی، دقت داشتن به status codes درج شدهی در OpenAPI Spec است که در قسمتهای چهارم و پنجم سری «مستند سازی ASP.NET Core 2x API توسط OpenAPI Swagger» آنها را بررسی کردیم.
در اینجا نه تنها سرویسی جهت تعامل با API ما تولید شدهاست، بلکه معادل تایپاسکریپتی DTOهای برنامه را نیز تولید کردهاست:
- چرا Web Components؟
- وضعیت پشتیبانی و به کار گیری Web Components
- توسعه چند کامپوننت نمونه با استفاده از Web Components
- بررسی ابزارهای جانبی
- استفاده به شکل Framework agnostic
آموزش TypeScript #1
در تصویر ذیل یک مقایسه کوتاه بین CoffeeScript و TypeScript را مشاهده میکنید.
با TypeScript چه چیزهایی به دست خواهیم آورد؟
یک نکته مهم این است که این زبان به خوبی در Visual Studio پشتیبانی میشود و قابلیت Intellisense نوشتن برنامه به این زبان را دلپذیرتر خواهد کرد و از طرفی دیگر به نظر من یکی از مهمترین مزیت هایی که TypeScript در اختیار ما قرار میدهد این است که میتوانیم به صورت Syntax آشنای شی گرایی کد نویسی کنیم و خیلی راحتتر کدهای خود را سازمان دهی کرده و از نوشتن کدهای تکراری اجتناب کنیم.
یکی دیگر از مزیتهای مهم این زبان این است که این زبان از Static Typing به خوبی پشتیبانی میکند. این بدین معنی است که شما ابتدا باید متغیرها را تعریف کرده و نوع آنها را مشخص نمایید و هم چنین در هنگام پاس دادن مقادیر به پارامترهای توابع باید حتما به نوع داده ای آنها دقت داشته باشید چون کامپایلر بین انواع داده ای در TypeScript تمایز قایل است و در صورت رعایت نکردن این مورد شما با خطا مواجه خواهید شد. این تمایز قایل شدن باعث میشود که برنامه هایی خواناتر داشته باشیم از طرفی باعث میشود که خطا یابی و نوشتن تست برای برنامه راحتتر و تمیزتر باشد. بر خلاف JavaScript، در TypeScript(به دلیل پشتیبانی از شی گرایی) میتوانیم علاوه بر داشتن کلاس، اینترفیس نیز داشته باشیم و در حال حاضر مزایای استفاده از اینترفیس بر کسی پوشیده نیست.
به دلیل اینکه کدهای TypeScript ابتدا کامپایل شده و بعد تبدیل به کدهای JavaScript میشوند در نتیجه قبل از رسیدن به مرحله اجرای پروژه، ما از خطاهای موجود در کد خود مطلع خواهیم شد.
البته این نکته را نیز فراموش نخواهیم کرد که این زبان تازه متولد شده است(سال 2012 توسط Anders Hejlsberg) و همچنان در حال توسعه است و این در حال حاضر مهمترین عیب این زبان میتواند باشد چون هنوز به پختگی سایر زبانهای اسکریپتی در نیامده است.
در ذیل یک مثال کوچک به زبان TypeScript و JavaScript را برای مقایسه در خوانایی و راحتی کد نویسی قرار دادم:
TypeScript:
class Greeter { greeting: string; constructor (message: string) { this.greeting = message; } greet() { return "Hello, " + this.greeting; } }
var Greeter = (function () { function Greeter(message) { this.greeting = message; } Greeter.prototype.greet = function () { return "Hello, " + this.greeting; }; return Greeter; })();
Program : یک برنامه TypeScript مجموعه ای از یک یا چند Source File است. این Source Fileها شامل کدهای پیاده سازی برنامه هستند ولی در خیلی موارد برای خوانایی بیشتر برنامه میتوان فقط تعاریف را در این فایلهای سورس قرار داد.
Module: ماژول در TypeScript شبیه به مفاهیم فضای نام یا namespace در دات نت است و میتواند شامل چندین کلاس یا اینترفیس باشد.
Class : مشابه به مفاهیم کلاس در دات نت است و دقیقا همان مفهوم را دارد. یک کلاس میتواند شامل چندین تابع و متغیر با سطوح دسترسی متفاوت باشد. در TypeScript مجاز به استفاده از کلمات کلیدی public و private نیز میباشید. یک کلاس در Typescript میتواند یک کلاس دیگر را توسعه دهد(ارث بری در دات نت) و چندین اینترفیس را پیاده سازی نماید.
Interface: یک اینترفیس فقط شامل تعاریف است و پیاده سازی در آن انجام نخواهد گرفت. یک اینترفیس میتواند چندین اینترفیس دیگر را توسعه دهد.
Function: معادل متد در دات نت است. میتواند پارامتر ورودی داشته باشد و در صورت نیاز یک مقدار را برگشت دهد.
Scope: دقیقا تمام مفاهیم مربوط به محدوده فضای نام و کلاس و متد در دات نت در این جا نیز صادق است.
آماده سازی Visual Studio برای شروع به کار
در ابتدا باید Template مربوطه به TypeScript را نصب کنید تا از طریف VS.Net بتوانیم به راحتی به این زبان کد نویسی کنیم. میتوانید فایل نصب را از اینجا دانلود کنید. بعد از نصب از قسمت Templateهای موجود گزینه Html Application With TypeScript را انتخاب کنید
یا از قسمت Add در پروژههای وب خود نظیر MVC گزینه TypeScript File را انتخاب نمایید.
در پست بعدی کد نویسی با این زبان را آغاز خواهیم کرد.