مهاجرت از project.json به csproj با استفاده از ویژوال استودیو 2017

در ویژوال استودیو 2017 و ابزار نهایی ASP.NET Core SDK، فایل تجدیدنظرشده csproj به فایل project.json ترجیح داده شد و project.json حذف شد. بعضی افراد تعجب کردند که چرا project.json در ویژوال استودیو ناپدید شده است. این تصمیم عمدتا برای حمایت از مشتریانی که وابسته به استفاده از MsBuild بوده و برای پشتیبانی از مهاجرت پروژه‌های بزرگ به NET Core. بوده است.

مهاجرت از project.json به csproj با استفاده از ویژوال استودیو 2017

در این آموزش، تجربیات شخصی، Steve Gordon، برای مهاجرت از project.json به csproj از زبان خودش گفته شده است. او تمام مراحل مهاجرت از ابتدا تا انتها و مشکلاتی که در این مهاجرت برایش رخ داده است را بیان می‌کند.

انتقال از project.json به csproj

در این مقاله می‌خواهم مراحل مهاجرت یک برنامه واقعی ASP.NET Core در ویژوال استودیو 2017 را که چند وقت پیش انجام دادم را بررسی کنم. من تمام این مراحل را همراه با مسائل و تداخلاتی که در این مسیر با آن مواجه شدم و راه‌حل‌های آن ثبت کرده‌ام.

اولین تلاش من در این پروسه تقریبا دو هفته پیش بود. در آن زمان من اولین ورژن RTM ویژوال استودیو 2017 را استفاده کردم و با یک فایل سولوشن allReady خودم، به سادگی شروع به کار کردم.

ویژوال استودیو متنی در رابطه با مهاجرت هر پروژه project.json را نمایش می‌دهد.

پس از پذیرش این پیام ویژوال استودیو این کار را انجام خواهد داد؛ طبق این پیام ویژوال استودیو فرمان مهاجرت دات نت (dotnet migrate) را فراخوانی می‌کند که تغییرات را برای شما انجام می‌دهد. من قصد داشتم تا برای مهاجرت از ویژوال استودیو 2017، به جای خط فرمان (command line) که فکر می‌کنم روشی است که اکثرا با آن کار می‌کنند، استفاده کنم.

در طی مهاجرت، که فقط چند ثانیه طول می‌کشد، یک پنجره پیش‌روی از ویژوال استودیو خواهید دید.

پس از اتمام مهاجرت، گزارشی از مهاجرت نشان داده می‌شود.

در ابتدا فکر کردم که همه چیز به خوبی پیش رفت. درحقیقت، زمانی که سعی می‌کردم چیزها را بازسازی کرده و بسازم همه چیز مثبت نبود. 982 خطای مبهم و 3 هشدار به من نشان داده شد.

تلاش مجدد

یک بار دیگر سعی کردم تا این مهاجرت را انجام دهم. آخرین نسخه برنامه خود را گرفتم و قبل از شروع، ویژوال استودیو 2017 را آپدیت کردم.

مراحل قبل را دوباره تکرار کردم. اگرچه نتایج هنوز عالی به نظر نمی‌رسید، اما این بار پیشرفت نسبتا بهتری داشتم. اولین نکته: همیشه مهاجرت را با آخرین آپدیت IDE انجام دهید! این بار 199 خطا و 2 هشدار داشتم.

بیشتر خطاها مربوط به وابستگی‌ها بود، چنان که به نظر می‌رسید مشکل از بازسازی است. من سعی کردم سولوشن را مرتب کنم، مجددا وپژوال استودیو را ریست کردم و حتی به صورت دستی فولدرهای bin و obj را حذف کردم. هر دفعه با خطاهای قرمز مواجه می‌شدم.

در این لحظه به سراغ گوگل رفتم و پیشنهادی برای پاک کردن حافظه نهان (cache) محلی nugget پیدا کردم. به USERPROFILE%/.nuget% هدایت شدم و محتویات را پاک کردم.

پس از انجام این کار، کمی کارها بهتر شد. خطاها رفع شدند، اما هنوز تعدادی هشدار وجود داشت و سایت اجرا نشد.

هشدار دوم کمی عجیب بود.

The referenced project ‘..\..\Backup\Web-App\AllReady\AllReady.csproj’ does not exist.

پروژه unit test به پروژه وب رفرنس داده شده بود اما با استفاده از مسیر فولدر backup. فولدر backup در طول مهاجرت ساخته می‌شود تا فایل‌های اصلی project.json و xproj را نگه داشته تا در صورت نیاز به بازگشت به حالت قبلی برگردد. البته این فولدر شامل فایل csproj نیست. من رفرنس را حذف کردم و دوباره اضافه کردم، و فولدر درست را پیدا کرد.

همچنین فولدر backup را به خارج از ساختار سولوشن اصلی خود بردم.

در این مرحله خطاها کم شدند اما هنوز 29 تا هشدار وجود داشت. برای اینکه مطمئن شوم مشکل از ویژوال استودیوی 2017 نباشد، سعی کردم با استفاده از خط فرمان، دستورات دات نت را به طور مستفیم بازسازی کنم. با این حال، هشدارها همچنان پابرجا بود.

در ویژوال استودیو، هشدار به این صورت بود:

Detected package downgrade: Microsoft.Extensions.Configuration.Abstractions from 1.1.0 to 1.0.2

تلاش برای اجرای برنامه در این مرحله منجر به exception زیر شد:

System.IO.FileLoadException: ‘Could not load file or assembly 
‘Microsoft.Extensions.Configuration.Abstractions, Version 1.1.0.0 … The 
located assembly’s manifest definition does not match the assembly reference.

بخاطر برخی دلایل مهاجرت، ورژن 1.1.0 برای وابستگی Microsoft.VisualStudio.Web.BrowserLink ،وقتی در فایل csproj ایجاد شد، را انتخاب کردم.

<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.1.0" />

راه‌حل این بود که آن را به 1.0.1 تغییر دهم چون در حال حاضر allReady  جریان LTS در ASP.NET Core را هدف قرار داده بود. تمام وابستگی‌های دیگر با ورژن LTS خودشان ثبت شدند. این وابستگی‌های x.1.1 باعث ایجاد تناقضات مربوط به ورژن شد.

<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.0.1" />

در این مرحله، کارها کمی بیشتر شد. حالا یک هشدار برای پروژه web داشتم. این هشدار اظهار داشت که (AddUserSecrets(IConfigurationBuilder  اکنون یک متد منسوخ‌شده است.

‘ConfigurationExtensions.AddUserSecrets(IConfigurationBuilder)’ is 
obselete. ‘This method is obsolete and will be removed in a 
future version. The recommended alternative is .AddUserSecrets(string userSercretsId) 
or .AddUserSecrets<TStartup>()..’

هشدار به این معنی بود که در حال حاضر ما انتظار داریم که در کلید محرمانه کاربر یک رشته برای متد یا استفاده از  .AddUserSecrets<TStartup>که سینتکس آن (AddUserSecrets(this IConfigurationBuilder configuration, Assembly assembly می‌باشد، پاس داده شود. قبلا محل ذخیره‌سازی ID محرمانه کاربر فایل project.json بود. اکنون به یک  assembly attribute منتقل شده است. overload قبلی بازگشت Assembly صحیح را بر عهده نداشت، بنابراین این مسأله می‌توانست مشکل‌ساز باشد.

بنابراین من خط مورد نظر را در Startup.cs از

builder.AddUserSecrets();

به

builder.AddUserSecrets("aspnet5-AllReady-468aac76-4430-43e6-848e-f4a3b90d61d0");

تغییر دادم.

تغییرات Test Project

در این مرحله پروژه web ساخته شده بود اما در پروژه test مشکلاتی وجود داشت:

Found conflicts between different versions of the same dependent
assembly that could not be resolved. These reference conflicts are listed 
in the build log when log verbosity is set to detailed.

برخی از وابستگی‌هایی که ما استفاده کرده‌ بودیم ورژن‌های جدیدتر بود بنابراین حدس زدم که شاید نیاز به آپدیت Xunit / test باشد. من این سه وابستگی را تغییر دادم:

<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0-preview-20170106-08" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0-beta5-build1225" />
<PackageReference Include="xunit" Version="2.2.0-beta5-build3474" />

به

<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<PackageReference Include="xunit" Version="2.2.0" />

درنهایت کل سولوشن ساخته شد، تست اجرا شد و توانستم وب‌سایت را به صورت لوکال اجرا کنم.

auto complete نبودن

در ویژوال استودیوی 2015 تکمیل خودکار (auto complete) برای وابستگی‌ها از NuGet هنگام ویرایش project.json را داشتیم. این روند در ویژوال استودیوی 2017 دیگر نیست که اصلا خوب نیست. حالا مجبوریم که از NuGet Package Manager استفاده کنیم که سرعت را پایین می‌آورد. اما متوجه شدم که autocomplete ممکن است برگردد، اما خیلی بد است که در این انتشار آن را نداریم.

بررسی ساده‌تر

شخصا، من هنوز فرمت project.json را برای خوانایی ترجیح می‌دهم. هنوز کمی اختلال در XML که در ورژن JSON داشتیم، وجود دارد. به گفته کارشناسان، کارهایی که در قالب تجدیدنظرشده csproj انجام شده بسیار خوب است و پیشرفت وسیعی در csproj گذشته رخ داده است.

نتیجه‌گیری

به طور کلی این فرآیند، خیلی سخت نبود. Visual Studio و dotnet migrate بیشتر کارها را برای من انجام دادند. بازسازی وابستگی‌هایی که بدون پاک کردن کش کار نمی‌کردند، مشکل غیرمنتظره‌ای بود.

Csproj پیشرفت بزرگی در آنچه که ما در گذشته داشتیم، محسوب می‌شود، بنابراین اگر هرگز project.json را ندیده‌اید، چیزی را از دست نداده‌اید و  پیشرفتی در آن رخ داه است که می‌توانید هم اکنون از آن استفاده کرده و لذت ببرید.

آموزش سی شارپ