من از نگارش ASP.NET Core 3.0 استفاده میکنم؛
با وجود اینکه در پروژهام از متا پکیج Microsoft.AspNetCore.All یا بستهی Microsoft.AspNetCore.App استفاده نشده، برای اجرای پروژه پابلیش شده بر روی سرور (بدلیل مواجه با خطای HTTP Error 500.31 - ANCM Failed to Find Native Dependencies ) مجبور به نصب .NET Core SDK شدم؛ مشکل از کجاست؟
آن پروژه برای NET Core 2.2. تنظیم شده. احتمالا پروژه را به نگارش 3 ارتقاء دادید که خطای زیر را دریافت کردید:
The collection type 'Newtonsoft.Json.Linq.JToken' is not supported
ارتقاء به ASP.NET Core 3.0: محدود شدن امکان تزریق وابستگیها در سازندهی کلاس آغازین برنامه
یکی از تغییرات مهم ASP.NET Core 3.0 نسبت به نگارشهای قبلی، جنریک شدن Host آن است (چون حالتهای هاستینگ بیشتری را نسبت به حالت صرف MVC پشتیبانی میکند). به این ترتیب HostBuilder نگارش 2x:
اکنون در نگارش 3x به این صورت در آمدهاست:
این مورد، یک تغییر مهم را هم در وضعیت تزریق وابستگیهای سفارشی در کلاس آغازین برنامه ایجاد کردهاست: در نگارش 3x، فقط و فقط سرویسهای IHostEnvironment ،IWebHostEnvironment و IConfiguration را میتوانید به سازندهی کلاس آغازین آن تزریق کنید.
علت اینجا است که در ASP.NET Core 3x، یک باگ بسیار مهم سیستم تزریق وابستگیهای ASP.NET Core برطرف شدهاست: اکنون فقط یک dependency injection container به ازای کل برنامهی ASP.NET Core 3x ساخته میشود. در نگارشهای قبلی، یک container برای برنامه و یک container مجزا برای host تولید میشدند. در این حالت اگر یک سرویس Singleton را در فایل program.cs معرفی میکردید:
برخلاف تصور، این سرویس Singleton رفتار نمیکرد؛ چون همانطور که عنوان شد، دو container، برنامه را مدیریت میکردند (یعنی دوبار توسط دو ظرف متفاوت نگهدارندهی اشیاء، وهله سازی میشد) که اکنون در نگارش 3x به یک مورد کاهش یافتهاست.
در اینجا هرچند متد ConfigureServices وجود دارد، اما اگر از آن استفاده کنید، سرویس معرفی شدهی توسط آن، در سازندهی کلاس Startup شناسایی نمیشود.
یکی از تغییرات مهم ASP.NET Core 3.0 نسبت به نگارشهای قبلی، جنریک شدن Host آن است (چون حالتهای هاستینگ بیشتری را نسبت به حالت صرف MVC پشتیبانی میکند). به این ترتیب HostBuilder نگارش 2x:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>();
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
علت اینجا است که در ASP.NET Core 3x، یک باگ بسیار مهم سیستم تزریق وابستگیهای ASP.NET Core برطرف شدهاست: اکنون فقط یک dependency injection container به ازای کل برنامهی ASP.NET Core 3x ساخته میشود. در نگارشهای قبلی، یک container برای برنامه و یک container مجزا برای host تولید میشدند. در این حالت اگر یک سرویس Singleton را در فایل program.cs معرفی میکردید:
WebHost.CreateDefaultBuilder() .UseStartup<Startup>() .ConfigureServices(services => services.AddSingleton<MySingleton>()) .Build() .Run();
در اینجا هرچند متد ConfigureServices وجود دارد، اما اگر از آن استفاده کنید، سرویس معرفی شدهی توسط آن، در سازندهی کلاس Startup شناسایی نمیشود.
ارتقاء به ASP.NET Core 3.0 و
تغییرات نقطهی آغازین برنامه
ASP.NET Core 3.0 از Generic Host بجای Web Host قبلی استفاده میکند. در این حالت فایل Program.cs آن از:
public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>(); }
public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); }
در این حالت هاستینگ برنامه دیگر به Kestrel و یا حتی خود ASP.NET Core وابسته نخواهد بود. یعنی میتوان هاستی را ایجاد کرد که به همراه راه اندازی وب سرور Kestrel نباشد. علت این جنریک شدن چیست؟
در نگارش سوم، هاستهای دیگری هم معرفی شدهاند؛ مانند امکان اجرای یک worker service بدون راه اندازی یک وب سرور و یا Blazor از روش هاستینگ متفاوتی درون یک web assembly استفاده میکند: «ارتقاء به NET Core 3.0.: پشتیبانی از ایجاد سرویسهای پسزمینه»
در نگارش سوم، هاستهای دیگری هم معرفی شدهاند؛ مانند امکان اجرای یک worker service بدون راه اندازی یک وب سرور و یا Blazor از روش هاستینگ متفاوتی درون یک web assembly استفاده میکند: «ارتقاء به NET Core 3.0.: پشتیبانی از ایجاد سرویسهای پسزمینه»
یک نکته: جزئیات متد CreateDefaultBuilder و سرویسهایی را که به صورت خودکار اضافه میکند، در اینجا در فایل src/DefaultBuilder/src/WebHost.cs میتوانید مشاهده کنید.
این شمارهای که ارسال کردید «core\3.0.0-preview-18579-0056\lib» مربوط به 5 ماه قبل هست و با نگارش «3 پیشنمایش 4» ای که عنوان کردید سازگاری ندارد. اگر مطمئن هستید که SDK درستی را نصب کردید، نیاز است تمام اسمبلیهای تمام پروژهها را هم یکدست کنید (پس از اصلاح دستی تمام TargetFrameworkهای موجود).
dotnet tool update --global dotnet-outdated dotnet outdated -u
یک نکتهی تکمیلی: دریافت خطای «HTTP Error 502.5 — ANCM Out-Of-Process Startup Failure»
راه حل: پس از نصب SDK جدید، یکبار dotnet restore را اجرا کنید تا شماره نگارش بستهی Microsoft.AspNetCore.App به روز شود؛ یا از روش زیر استفاده کنید:
dotnet tool update -g dotnet-outdated dotnet outdated -u dotnet restore
در صورتی که امروز اقدام به گرفتن ویژوال استدیو کنید، به جای 15.8 شما 15.9 را خواهید گرفت که خیلی هم خوب است. فقط بهتر است به جای این که از ویندوز 10 ورژن 17134 استفاده کنید، از 17763 استفاده کنید که به روزتر است و SDK آن به صورت پیش فرض توسط Visual Studio 15.9 نصب میشود. در صورتی که بخواهید در ویندوز 10 نگارش 17134 یا 16299 کد بزنید، در موقع نصب Visual Studio 15.9 درخواست نصب SDKهای آن را هم بدهید. همان طور که گفتیم، نباید کمتر از 16299 هم باشید. اساسا همان 16299 نیز دارای دردسر و باگ زیادی است، بهتر است 17134 یا 17763 باشید.
با توجه به این که Android Http Client Handler که از TLS 1.2 استفاده میکند و Performance بهتری نیز دارد، لااقل به Android 5 برای کار کردن احتیاج دارد، بهتر است حداقل ورژن اندروید برای برنامه تان را روی Android 5 تنظیم کنید.
در مورد بهبود سرعت بیلد در VS 15.9 هم در نظر داشته باشید که Target Android SDK تان باید روی Android SDK 9.1 باشد. توجه کنید که پروژه مثال XamApp در لحظه نگارش این کامنت روی Android SDK 8.1 است.
ارتقاء به ASP.NET Core 3.0
در نگارش 3 دیگر از بستهی Microsoft.AspNetCore.Mvc.Razor.ViewCompilation پشتیبانی نمیشود. در اینجا برای برخورداری از مزایای پیشکامپایل فایلهای razor، پروژههای وب باید از SDK زیر
<Project SDK="Microsoft.NET.Sdk.Web"> ... </Project>
<Project SDK="Microsoft.NET.Sdk.Razor"> ... </Project>
کمی بالاتر توضیح دادم. این «local runtime store» را که جستجو میکند بر اساس شماره SDK، تمام فایلها را به همراه دارد و به همین جهت حجم ارائهی برنامه در این حالت بسیار کم است. برای مثال شما از نگارش 2.1.1 استفاده میکنید (مطابق خطای ارسالی) و به احتمال زیاد بر روی سرور فقط 2.1.0 نصب هست و run time store فعلی فاقد فایلهای 2.1.1 هست. به همین جهت هست که یا باید SDK جدید را نصب کنید و یا فایلهای اضافی آنرا دستی ارائه کنید.