پروژه متن باز فیس بوک جهت باگ یابی
شاید سادهترین تعریف برای Saltarelle این باشد که «کامپایلریست که کدهای C# را به جاوا اسکریپت تبدیل میکند». محاسن زیادی را میتوان برای اینگونه کامپایلرها نام برد؛ مخصوصا در پروژههای سازمانی که نگهداری از کدهای جاوا اسکریپت بسیار سخت و گاهی خارج از توان است و این شاید مهمترین عامل ظهور ابزارهای جدید از قبیل Typescript باشد.
در هر صورت اگر حوصله و وقت کافی برای تجهیز تیم نرم افزاری، به دانش یک زبان جدید مانند Typescript نباشد، استفاده از توان و دانش تیم تولید، از زبان C# سادهترین راه حل است و اگر ابزاری مطمئن برای استفاده از حداکثر قدرت JavaScript همراه با امکانات نگهداری و توسعه کدها وجود داشته باشد، بی شک Saltarelle یکی از بهترینهای آنهاست.
قبلا کامپایلر هایی از این دست مانند Script# وجود داشتند، اما فاقد همه امکانات C# بوده وعملا قدرت کامل C# در کد نویسی وجود نداشت. اما با توجه به ادعای توسعه دهندگان این کامپایلر سورس باز در استفادهی حداکثری از کلیه ویژگیهای C# 5 و با وجود Library های متعدد میتوان Saltarelle را عملا یک کامپایلر موفق در این زمینه دانست.
برای استفاده از Saltarelle در یک برنامه وب ساده باید یک پروژه Console Application به Solution اضافه کرد و پکیج Saltarelle.Compiler را از nuget نصب نمایید. بعد از نصب این پکیج، کلیه Reference ها از پروژه حدف میشوند و هر بار Build توسط کامپایلر Saltarelle انجام میشود. البته با اولین Build، مقداری Error را خواهید دید که برای از بین بردنشان نیاز است پکیج Saltarelle.Runtime را نیز در این پروژه نصب نمایید:
PM> Install-Package Saltarelle.Compiler PM> Install-Package Saltarelle.Runtime
در صورتیکه کماکان Build نهایی با Error همرا بود، یکبار این پروژه را Unload و سپس مجددا Load نمایید
UI یک پروژه وب MVC است و Client یک Console Application که پکیجهای مورد نیاز Saltarelle روی آن نصب شده است.
در صورتیکه پروژه را Build نماییم و نگاهی به پوشهی Debug بیاندازیم، یک فایل JavaScript همنام پروژه وجود دارد:
برای اینکه بعد از هر بار Build ، فایل اسکریپت به پوشهی مربوطه در پروژه UI منتقل شود کافیست کد زیر را در Post Build پروژه Client بنویسیم:
copy "$(TargetDir)$(TargetName).js" "$(SolutionDir)SalratelleSample.UI\Scripts"
اکنون پس از هر بار Build ، فایل اسکریپت مورد نظر در پوشهی Scripts پروژه UI آپدیت میشود:
در ادامه کافیست فایل اسکریپت را به layout اضافه کنیم.
<script src="~/Scripts/SaltarelleSample.Client.js"></script>
در پوشهی Saltarelle.Runtime در پکیجهای نصب شده، یک فایل اسکریپت به نام mscorlib.min.js نیز وجود دارد که حاوی اسکریپتهای مورد نیاز Saltarelle در هنگام اجراست. آن را به پوشه اسکریپتهای پروژه UI کپی نمایید و سپس به Layout اضافه کنید.
<script src="~/Scripts/mscorlib.min.js"></script> <script src="~/Scripts/SaltarelleSample.Client.js"></script>
حال نوبت به اضافه نمودن libraryهای مورد نیازمان است. برای دسترسی به آبجکت هایی از قبیل document, window, element و غیره در جاوااسکریپت میتوان پکیج Saltarelle.Web را در پروژهی Client نصب نمود و برای دسترسی به اشیاء و فرمانهای jQuery، پکیج Salratelle.jQuery را نصب نمایید.
> Install-Package Saltarelle.Web > Install-Package Saltarelle.jQuery
به این libraryها imported library میگویند. در واقع، در زمان کامپایل، برای این libraryها فایل اسکریپتی تولید نمیشود و فقط آبجکتهای #C هستند که که هنگام کامپایل تبدیل به کدهای ساده اسکریپت میشوند که اگر اسکریپت مربوط به آنها به صفحه اضافه نشده باشد، اجرای اسکریپت با خطا مواجه میشود.
به طور سادهتر وقتی از jQuery library استفاده میکنید هیچ فایل اسکریپت اضافهای تولید نمیشود، اما باید اسکریپت jQuery به صفحه شما اضافه شده باشد.
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
مثال ما یک اپلیکیشن ساده برای خواندن فیدهای همین سایت است. ابتدا کدهای سمت سرور را در پروژه UI می نویسیم.
کلاسهای مورد نیاز ما برای این فید ریدر:
public class Feed { public string FeedId { get; set; } public string Title { get; set; } public string Address { get; set; } } public class Item { public string Title { get; set; } public string Link { get; set; } public string Description { get; set; } }
و یک کلاس برای مدیریت منطق برنامه
public class SiteManager { private static List<Feed> _feeds; public static List<Feed> Feeds { get { if (_feeds == null) _feeds = CreateSites(); return _feeds; } } private static List<Feed> CreateSites() { return new List<Feed>() { new Feed(){ FeedId = "1", Title = "آخرین تغییرات سایت", Address = "https://www.dntips.ir/rss.xml" }, new Feed(){ FeedId = "2", Title = "مطالب سایت", Address = "https://www.dntips.ir/feeds/posts" }, new Feed(){ FeedId = "3", Title = "نظرات سایت", Address = "https://www.dntips.ir/feeds/comments" }, new Feed(){ FeedId = "4", Title = "خلاصه اشتراک ها", Address = "https://www.dntips.ir/feed/news" }, }; } public static IEnumerable<Item> GetNews(string id) { XDocument feedXML = XDocument.Load(Feeds.Find(s=> s.FeedId == id).Address); var feeds = from feed in feedXML.Descendants("item") select new Item { Title = feed.Element("title").Value, Link = feed.Element("link").Value, Description = feed.Element("description").Value }; return feeds; } }
کلاس SiteManager فقط یک لیست از فیدها دارد و متدی که با گرفتن شناسهی فید ، یک لیست از آیتمهای موجود در آن فید ایجاد میکند.
حال دو ApiController برای دریافت دادهها ایجاد میکنیم
public class FeedController : ApiController { // GET api/<controller> public IEnumerable<Feed> Get() { return SiteManager.Feeds; } } public class ItemsController : ApiController { // GET api/<controller>/5 public IEnumerable<Item> Get(string id) { return SiteManager.GetNews(id); } }
در View پیشفرض که Index از کنترلر Home است، یک Html ساده برای
فرم صفحه اضافه میکنیم
<div> <div> <h2>Feeds</h2> <ul id="Feeds"> </ul> </div> <div> <h2>Items</h2> <p id="FeedItems"> </p> </div> </div>
در المنت Feeds لیست فیدها را قرار میدهیم و در FeedItems آیتمهای مربوط به هر فید. حال به سراغ کدهای سمت کلاینت میرویم و به جای جاوا اسکریپت از Saltarelle استفاده میکنیم.
کلاس Program را از پروژه Client باز میکنیم و متد Main را به شکل زیر تغییر میدهیم:
static void Main() { jQuery.OnDocumentReady(() => { FillFeeds(); }); }
بعد از کامپایل شدن، کد #C شارپ بالا به صورت زیر در میآید:
$SaltarelleSample_Client_$Program.$main = function() { $(function() { $SaltarelleSample_Client_$Program.$fillFeeds(); }); }; $SaltarelleSample_Client_$Program.$main();
و این همان متد معروف jQuery است که Saltarelle.jQuery برایمان ایجاد کرده است.
متد FillFeeds را به شکل زیر پیاده سازی میکنیم
private static void FillFeeds() { jQuery.Ajax(new jQueryAjaxOptions() { Url = "/api/feed", Type = "GET", Success = (d,t,r) => { // Fill var ul = jQuery.Select("#Feeds"); jQuery.Each((List<Feed>)d, (idx,i) => { var li = jQuery.Select("<li>").Text(i.Title).CSS("cursor", "pointer"); li.Click(eve => { FillData(i.FeedId); }); ul.Append(li); }); } }); }
آبجکت jQuery، متدی به نام Ajax دارد که یک شی از کلاس jQueryAjaxOptions را به عنوان پارامتر میپذیرد. این کلاس کلیه خصوصیات متد Ajax در jQuery را پیاده سازی میکند. نکته شیرین آن توانایی نوشتن lambda برای Delegate هاست.
خاصیت Success یک Delegate است که 3 پارامتر ورودی را میپذیرد.
public delegate void AjaxRequestCallback(object data, string textStatus, jQueryXmlHttpRequest request);
data همان مقداریست که api باز میگرداند که یک لیست از Feed هاست. برای زیبایی کار، من یک کلاس Feed در پروژه Client اضافه میکنم که خصوصیاتی مشترک با کلاس اصلی سمت سرور دارد و مقدار برگشی Ajax را به آن تبدیل میکنم.
کلاس Feed و Item
[PreserveMemberCase()] public class Feed { //[ScriptName("FeedId")] public string FeedId; //[ScriptName("Title")] public string Title; //[ScriptName("Address")] public string Address; } [PreserveMemberCase()] public class Item { // [ScriptName("Title")] public string Title; // [ScriptName("Link")] public string Link; // [ScriptName("Description")] public string Description; }
jQuery.Each((List<Feed>)d, (idx,i) => { var li = jQuery.Select("<li>").Text(i.Title).CSS("cursor", "pointer"); li.Click(eve => { FillData(i.FeedId); }); ul.Append(li); });
به ازای هر آیتمی که در شیء بازگشتی وجود دارد، با استفاد از متد each در jQuery یک li ایجاد میکنیم. همان طور که میبینید کلیه خواص، به شکل Fluent قابل اضافه شدن میباشد. سپس برای li یک رویداد کلیک که در صورت وقوع، متد FillData را با شناسه فید کلیک شده فراخوانی میکند و در آخر li را به المنت ul اضافه میکنیم.
برای هر کلیک هم مانند مثال بالا api را با شناسهی فید مربوطه فراخوانی کرده و به ازای هر آیتم، یک سطر ایجاد میکنیم.
private static void FillData(string p) { jQuery.Ajax(new jQueryAjaxOptions() { Url = "/api/items/" + p, Type = "GET", Success = (d, t, r) => { var content = jQuery.Select("#FeedItems"); content.Html(""); foreach (var item in (List<Item>)d) { var row = jQuery.Select("<div>").AddClass("row").CSS("direction", "rtl"); var link = jQuery.Select("<a>").Attribute("href", item.Link).Text(item.Title); row.Append(link); content.Append(row); } } }); }
در این مثال ما از Saltarelle.jQuery برای استفاده از jQuery.js استفاده نمودیم. libraryهای متعددی برای Saltarelle از قبیل linq,angular,knockout,jQueryUI,nodeJs ایجاد شده و همچنین قابلیتهای زیادی برای نوشتن imported libraryهای سفارشی نیز وجود دارد.
مطمئنا استفاده از چنین کامپایلرهایی راه حلی سریع برای رهایی از مشکلات متعدد کد نویسی با جاوا اسکریپت در نرم افزارهای بزرگ مقیاس است. اما مقایسه آنها با ابزارهایی از قبیل typescript احتیاج به زمان و تجربه کافی در این زمینه دارد.
- استفاده از Postman برای آزمایش یک برنامهی Web API
- استفاده از strest برای آزمایش یک برنامهی Web API
روش سومی هم برای انجام اینکار وجود دارد که به صورت توکار از زمان ارائهی ASP.NET Core 2.1 به همراه TestServer آزمایشی آن میسر شد. این روش در نگارش 3.1، با تغییر روش تعریف فایل program.cs، جهت سازگاری آن با آزمونهای یکپارچگی/آزمایش کل سیستم، بهبود یافتهاست که خلاصهای از آن را در این مطلب بررسی میکنیم.
آزمونهای یکپارچگی در ASP.NET Core
آزمونهای یکپارچگی، برخلاف آزمونهای واحد که عموما از اشیاء تقلیدی استفاده میکنند، دقیقا بر روی همان سیستمی که قرار است به کاربر نهایی ارائه شود، اجرا میشوند. به همین جهت تنظیمات اولیهی آنها کمی بیشتر است و همچنین زمان اجرای آنها نیز به علت وابستگی به بانک اطلاعاتی واقعی، فایل سیستم، شبکه و غیره، نسبت به آزمونهای واحد بیشتر است.
برای ایجاد آزمونهای یکپارچگی در برنامههای ASP.NET Core، حداقل سه مرحله باید طی شوند:
الف) ایجاد یک class library که ارجاعی را به پروژهی اصلی دارد. این پروژه حاوی آزمایشهای ما خواهد بود.
ب) راه اندازی یک هاست وب آزمایشی برای ارسال درخواستها به آن و دریافت پاسخهای نهایی.
ج) استفاده از یک test runner (انواع و اقسام فریم ورکهای unit testing) برای اجرای آزمایشها
ایجاد یک پروژهی کتابخانه برای هاست و اجرای آزمایشهای یکپارچگی
فرض کنید میخواهیم برای همان پروژهی ایجاد JWTها، آزمایش یکپارچگی بنویسیم. پس از ایجاد یک پروژهی کتابخانهی جدید که قرار است هاست آزمایشهای ما شود، نیاز است محتوای فایل csproj آنرا به صورت زیر تغییر داد:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netcoreapp3.1</TargetFramework> <NoWarn>RCS1090</NoWarn> </PropertyGroup> <ItemGroup> <ProjectReference Include="..\ASPNETCore2JwtAuthentication.WebApp\ASPNETCore2JwtAuthentication.WebApp.csproj" /> </ItemGroup> <ItemGroup> <None Include="..\ASPNETCore2JwtAuthentication.WebApp\appsettings.json" CopyToOutputDirectory="PreserveNewest" /> </ItemGroup> <ItemGroup> <Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c329}" /> </ItemGroup> <ItemGroup> <PackageReference Include="fluentassertions" Version="5.10.3" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="3.1.8" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" /> <PackageReference Include="MSTest.TestAdapter" Version="2.1.2" /> <PackageReference Include="MSTest.TestFramework" Version="2.1.2" /> </ItemGroup> </Project>
1) TargetFramework آن باید به netcoreapp تنظیم شود.
2) باید ارجاع مستقیمی به کل پروژهی نهایی WebApp در آن وجود داشته باشد. چون در ادامه میخواهیم فایل Program.cs آنرا برای راه اندازی یک هاست وب آزمایشی، فراخوانی کنیم.
3) بستهی نیوگتی که کار راه اندازی هاست وب آزمایشی را انجام میدهد، Microsoft.AspNetCore.Mvc.Testing نام دارد. این بسته، کار کپی فایلهای پروژهی اصلی و همچنین تنظیم مسیر پروژه را به این مسیر جدید نیز انجام میدهد.
4) روش افزودن بستههای MSTest را مشاهده میکنید.
5) همچنین جهت سادهتر شدن بررسی نتایج آزمونهای انجام شده میتوان از fluentassertions نیز استفاده کرد.
راه اندازی هاست وب آزمایشی جهت انجام آزمونهای واحد
پس از انجام تنظیمات ابتدایی پروژهی آزمون یکپارچگی، نیاز است یک WebApplicationFactory سفارشی را ایجاد کرد:
using ASPNETCore2JwtAuthentication.WebApp; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.TestHost; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; namespace ASPNETCore2JwtAuthentication.IntegrationTests { public class CustomWebApplicationFactory : WebApplicationFactory<Program> { protected override IWebHostBuilder CreateWebHostBuilder() { var builder = base.CreateWebHostBuilder(); builder.ConfigureLogging(logging => { //TODO: ... }); return builder; } protected override void ConfigureWebHost(IWebHostBuilder builder) { builder.ConfigureTestServices(services => { // Don't run `IHostedService`s when running as a test services.RemoveAll(typeof(IHostedService)); }); } } }
در ادامه روش سفارشی سازی WebApplicationFactory را مشاهده میکنید. برای مثال اگر خواستید سرویسها و تنظیمات پیشفرض برنامهی اصلی را تغییر دهید میتوانید متد CreateWebHostBuilder را بازنویسی کنید و یا اگر خواستید سرویس جدیدی را اضافه و یا حذف کنید، میتوان متد ConfigureWebHost را بازنویسی کرد.
استفاده از WebApplicationFactory سفارشی، جهت ایجاد یک HttpClient
هدف اصلی از ایجاد CustomWebApplicationFactory نه فقط راه اندازی یک هاست وب سفارشی است، بلکه توسط متد CreateClient آن میتوان به یک HttpClient دسترسی یافت که قابلیت ارسال اطلاعات را به برنامهی وبی که در پشت صحنه راه اندازی میشود، دارا است. کار CustomWebApplicationFactory شبیه به راه اندازی dotnet run در پشت صحنهاست. در اینجا دیگر نیازی نیست تا اینکار را به صورت دستی انجام داد. به همین جهت چون برنامهی وب اصلی به نحو متداولی در پشت صحنه اجرا میشود، عموما راه اندازی آن که شامل تنظیمات اولیه و یا حتی ایجاد بانک اطلاعاتی است، کمی کند است و اگر قرار باشد هربار اینکار صورت گیرد، به آزمونهای بسیار کندی خواهیم رسید. به همین جهت میتوان یک کلاس singleton را برای مدیریت تک وهلهی نهایی HttpClient آن به صورت زیر ایجاد کرد:
using System; using System.Threading; using System.Net.Http; namespace ASPNETCore2JwtAuthentication.IntegrationTests { public static class TestsHttpClient { private static readonly Lazy<HttpClient> _serviceProviderBuilder = new Lazy<HttpClient>(getHttpClient, LazyThreadSafetyMode.ExecutionAndPublication); /// <summary> /// A lazy loaded thread-safe singleton /// </summary> public static HttpClient Instance { get; } = _serviceProviderBuilder.Value; private static HttpClient getHttpClient() { var services = new CustomWebApplicationFactory(); return services.CreateClient(); //NOTE: This action is very time consuming, so it should be defined as a singleton. } } }
نوشتن اولین آزمون یکپارچگی
پس از تنظیم هاست وب آزمایشی و ایجاد یک HttpClient از پیش تنظیم شده که به آن اشاره میکند، اکنون میتوان اولین آزمون یکپارچگی را به صورت زیر نوشت:
using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Text.Json; using System.Threading.Tasks; using FluentAssertions; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace ASPNETCore2JwtAuthentication.IntegrationTests { [TestClass] public class JwtTests { [TestMethod] public async Task TestLoginWorks() { // Arrange var client = TestsHttpClient.Instance; // Act var token = await doLoginAsync(client); // Assert token.Should().NotBeNull(); token.AccessToken.Should().NotBeNullOrEmpty(); token.RefreshToken.Should().NotBeNullOrEmpty(); } [TestMethod] public async Task TestCallProtectedApiWorks() { // Arrange var client = TestsHttpClient.Instance; // Act var token = await doLoginAsync(client); // Assert token.Should().NotBeNull(); token.AccessToken.Should().NotBeNullOrEmpty(); token.RefreshToken.Should().NotBeNullOrEmpty(); // Act const string protectedApiUrl = "/api/MyProtectedApi"; client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken); var response = await client.GetAsync(protectedApiUrl); response.EnsureSuccessStatusCode(); // Assert var responseString = await response.Content.ReadAsStringAsync(); responseString.Should().NotBeNullOrEmpty(); var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; var apiResponse = JsonSerializer.Deserialize<MyProtectedApiResponse>(responseString, options); apiResponse.Title.Should().NotBeNullOrEmpty(); apiResponse.Title.Should().Be("Hello from My Protected Controller! [Authorize]"); } private static async Task<Token> doLoginAsync(HttpClient client) { const string loginUrl = "/api/account/login"; var user = new { Username = "Vahid", Password = "1234" }; var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Post, loginUrl) { Content = new StringContent(JsonSerializer.Serialize(user), Encoding.UTF8, "application/json") }); response.EnsureSuccessStatusCode(); var responseString = await response.Content.ReadAsStringAsync(); responseString.Should().NotBeNullOrEmpty(); return JsonSerializer.Deserialize<Token>(responseString); } } }
- در هر آزمونی نیاز است در ابتدا به TestsHttpClient.Instance، که همان HttpClient ساخته شدهی توسط CustomWebApplicationFactory است، دسترسی یافت و همانطور که عنوان شد، دسترسی به وهلهای از HttpClient که به هاست وب آزمایشی برنامهی اصلی اشاره میکند، عموما بسیار زمانبراست و برای مثال در دو آزمایش نوشته شدهی در اینجا اگر قرا باشد هربار اینکار از صفر انجام شود، زمان به اتمام رسیدن این آزمایشها بسیار طولانی خواهد شد. به همین جهت طول عمر TestsHttpClient را singleton تعریف کردیم تا فقط یکبار کار برپایی وب سرور آزمایشی در پشت صحنه انجام شود.
- سپس مابقی کار، همان روش استاندارد کار با HttpClient است. در ابتدا درخواستی را به سمت سرور آزمایشی که در پشت صحنه در حال اجرا است، ارسال میکنیم. چون HttpClient دریافتی توسط CustomWebApplicationFactory تنظیم شدهاست، دیگر نیازی به ذکر آدرس پایهی وب سایت مانند https://localhost:5001 نیست و آدرسهای ذکر شدهی در اینجا، نسبی هستند. سپس محتوای Response دریافتی از سرور را جهت تکمیل آزمایشات، بررسی خواهیم کرد.
یک نکته: اگر OpenAPI را در برنامههای Web API فعال کنید، میتوان با استفاده از ابزارهای تولید کد، کدهای مرتبط با HttpClient را نیز به صورت خودکار تولید و سپس از آنها در اینجا استفاده کرد.
اجرای آزمونهای یکپارچگی نوشته شده
چون ظاهر این آزمونها با آزمونهای واحد MSTest یا هر فریم ورک مشابه دیگری یکسان است، میتوان از امکانات IDEها برای اجرای آنها استفاده کرد و یا حتی میتوان دستور dotnet test را نیز در ریشهی این پروژهی جدید برای اجرای تمام آزمونهای نوشته شده، اجرا کرد:
کدهای کامل این مطلب را در اینجا میتوانید مشاهده کنید.
dotnet --list-sdks dotnet new globaljson --sdk-version 2.2.106
Roslyn #2
Roslyn از زمان ارائهی نگارش Visual Studio 14 CTP3 با ویژوال استودیو یکپارچه شد. بنابراین اگر از نگارش نهایی آن یعنی Visual Studio 2015 استفاده میکنید، اولین پیشنیاز کار با آن را در اختیار دارید. البته نگارش پیش نمایش آن نیز برای VS 2013 ارائه شد که در این تاریخ منسوخ شده درنظر گرفته میشود و دیگر به روز رسانی نخواهد شد. بنابراین نیاز است حتما Visual Studio 2015 را نصب کنید.
در حین نصب Visual Studio 2015 نیز باید گزینهی نصب SDK آنرا انتخاب کرده باشید، تا امکان تولید فایلهای VSIX مرتبط را پیدا کنید. از این جهت که قالبهای پروژهی Roslyn، امکان تولید افزونههای آنالیز کدها را نیز میسر میکنند.
علاوه بر اینها نیاز است Syntax Visualizer و قالبهای پروژهی مخصوص Roslyn را نیز جداگانه نصب کنید. برای این منظور به آدرس ذیل مراجعه کرده و افزونهی آنرا نصب کنید.
NET Compiler Platform SDK.
پس از نصب این افزونه، دو قابلیت جدید به Visual studio اضافه میشوند:
الف) در منوی view، ذیل گزینهی other windows، گزینهی جدیدی به نام Syntax visualizer اضافه شدهاست.
ب) ذیل گزینهی extensibility پنجرهی new project، تعدادی قالب پروژهی جدید مخصوص Roslyn نصب شدهاند.
البته باید دقت داشت که این قالبهای جدید برای نمایش در این لیست، حداقل نیاز به انتخاب دات نت 4.5.2 را دارند.
از Syntax visualizer جهت مشاهدهی ریز جزئیات ساختار دستوری کدهای جاری استفاده میشود:
زمانیکه گزینهی View->Other windows->Syntax visualizer را اجرا کردید، اندکی صبر کنید تا بارگذاری شود و سپس اشارهگر ویرایشگر را به قسمتی دلخواه حرکت دهید. در این حالت میتوان ساختار کدها را بر اساس تفسیر Roslyn مشاهده کرد. همچنین اگر در Syntax visualizer یک نود را انتخاب کنید، بلافاصله معادل آن در ادیتور ویژوال استودیو انتخاب میشود. از این ابزار جهت تولید آنالایزرهای مبتنی بر Roslyn زیاد استفاده میشود.
تغییرات خط فرمان Visual Studio 2015 نسبت به نگارشهای پیشین آن
خط فرمان Visual Studio 2015 به همراه کامپایلر قدیمی خط فرمان C# 5 و همچنین کامپایلر جدید مبتنی بر Roslyn مخصوص C# 6 است. این کامپایلرها را در مسیرهای ذیل میتوانید پیدا کنید:
کامپایلر جدید مبتنی بر Roslyn در مسیر C:\Program Files (x86)\MSBuild\14.0\Bin قرار دارد و کامپایلر قدیمی C# 5 در مسیر نصب دات نت فریم ورک یعنی C:\Windows\Microsoft.NET\Framework\v4.0.30319 قرار گرفتهاست.
همانطور که مشاهده میکنید، نگارش کامپایلر مبتنی بر Roslyn، یک است و شماره build آن، بیانگر تاریخ کامپایل آن است:
50618=2015/06/18
اکنون شاید این سؤال مطرح شود که کامپایلر پیش فرض کدام است؟ برای یافتن آن، به منوی استارت ویندوز مراجعه کرده و گزینهی developer command prompt for vs 2015 را اجرا کنید. در اینجا اگر دستور csc را اجرا کنید، خروجی آن همان کامپایلر مبتنی بر Roslyn است:
در همینجا اگر سوئیچ ? را برای مشاهدهی راهنمای کامپایلر خط فرمان Roslyn صادر کنید، یکی از گزینههای جدید آن، سوئیچ analyzer است:
C:\Program Files (x86)\Microsoft Visual Studio 14.0>csc /? Microsoft (R) Visual C# Compiler version 1.0.0.50618 Copyright (C) Microsoft Corporation. All rights reserved. Visual C# Compiler Options /analyzer:<file list> Run the analyzers from this assembly (Short form: /a)
همچنین این کامپایلر نسبت به نگارش قبلی آن، دارای سوئیچ و گزینهی parallel نیز میباشد که به کمک ساختارهای دادهی immutable جدید دات نت مسیر شدهاست.
نگاهی به NET 5.
For now, Microsoft's .NET Core milestones page shows .NET 5.0 about 53 percent complete, with 1,066 issues open and 1,216 issues closed.
Highlights of .NET 5 include:
- Developers will have more choice on runtime experiences.
- Java interoperability will be available on all platforms.
- Objective-C and Swift interoperability will be supported on multiple operating systems.
- CoreFX will be extended to support static compilation of .NET (ahead-of-time – AOT), smaller footprints and support for more operating systems.
سایتی مشابه W3Schools برای اندروید
سایتی مشابه W3Schools برای اندروید