Porting aplikasi WPF ke netcore 3.0

Rilis netcore 3.0 yang akan datang memungkinkan Anda menjalankan WPF di netcore. Prosedur terjemahan untuk satu proyek sederhana membutuhkan satu hingga dua hari. Masing-masing berikutnya jauh lebih cepat.







Persiapan dan konversi proyek



Langkah pertama dalam persiapan adalah menginstal dan menjalankan Portability Analyzer. Pada output, kita mendapatkan plat Excel di mana kita akan melihat seberapa banyak kode kita memenuhi persyaratan baru.





Prosedur untuk mengubah proyek lama diubah dalam beberapa tahap.


  1. Microsoft merekomendasikan untuk meningkatkan versi kerangka kerja ke .Net Framework 4.7.3 untuk proyek yang lebih lama.
  2. Konversi struktur proyek lama ke format baru. Ganti paket.konfigurasi dengan PackageReference.
  3. Ketiga, sesuaikan struktur file csproj ke format netcore.


Saya ingin berterima kasih kepada Emil Yangirov dengan laporannya tentang migrasi ke netcore, yang sangat berguna. Tautan ke laporannya.



Ternyata kami memutuskan untuk melewati tahap pertama. Tahap kedua menyiratkan kebutuhan untuk mengkonversi lebih dari 100 proyek. Bagaimana proses ini dilakukan dapat dibaca secara rinci di sini .


Kami memahami bahwa otomatisasi tidak dapat dihindari. Menggunakan solusi siap pakai: CsprojToVs2017 . Biarkan nama proyek tidak mengganggu Anda: utilitas juga mengonversi untuk Visual Studio 2019.



Apa yang akan terjadi


Ukuran file csproj akan berkurang. Karena apa? Semua file yang terhubung dengan kode sumber akan meninggalkan csproj, baris tambahan akan dihapus, dll.



- <Compile Include="Models\ViewModels\HistoryViewModel.cs" /> - <Compile Include="Properties\Settings.Designer.cs"> - <AutoGen>True</AutoGen> - <DependentUpon>Settings.settings</DependentUpon> - <DesignTimeSharedInput>True</DesignTimeSharedInput> - </Compile> 


Entri perpustakaan dan sub proyek yang terhubung akan berkurang.



 - <Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> - <HintPath>..\packages\NLog.4.3.3\lib\net45\NLog.dll</HintPath> - <Private>False</Private> - </Reference> - <ProjectReference Include="..\WpfCommon\WpfCommon.csproj"> - <Project>{7ce118f6-2978-42a7-9e6a-ee5cd3057e29}</Project> - <Name>WpfCommon</Name> - </ProjectReference> + <PackageReference Include="NLog" Version="4.6.7" /> + <ProjectReference Include="..\WpfCommon\WpfCommon.csproj" /> 


Pengaturan umum untuk beberapa proyek dapat dilakukan di Directory.BuildProps. Ini adalah file khusus yang dilihat oleh MsBuild.
Dengan analogi dengan .gitignore dan .editorconfig, kami memiliki file global dengan pengaturan umum.
Kami menambahkan pengaturan PropertyGroup pribadi untuk subdirektori / proyek ke file csproj tertentu. Detail dapat ditemukan di sini.



Ketergantungan



Ketergantungan lama untuk netframework. Anda harus menemukan paket alternatif atau serupa untuk nuget. Untuk banyak proyek, sudah ada paket Nuget yang mendukung netcore atau standar.



Misalnya, proyek menggunakan versi lama dari DI Unity. Saat beralih ke versi baru, saya harus memperbarui menggunakan dan memperbaiki kode di dua atau tiga tempat.


 using Microsoft.Practices.Unity -> using Unity; 


Dan mungkin itu akan cukup untuk meningkatkan semua versi paket. Dan untuk berjaga-jaga, restart studio.



Ubah csproj untuk menggunakan netcore



Dalam proyek yang menggunakan kontrol WPF, Anda perlu mengubah format ke Microsoft.NET.Sdk.WindowsDesktop:



 -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> - <PropertyGroup/> 

 +<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop"> + <PropertyGroup> + <TargetFramework>netcoreapp3.0</TargetFramework> + <AssemblyTitle>MyEnterpriseLibrary</AssemblyTitle> + <Product>MyEnterpriseLibrary</Product> + <OutputPath>..\bin\$(Configuration)\</OutputPath> + <UseWPF>true</UseWPF> + <!--    assemblyinfo    ,    --> + <GenerateAssemblyInfo>false</GenerateAssemblyInfo> </Project> 


Untuk ClassLibrary, tinggalkan saja tipe Microsoft.NET.Sdk:



 <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netcoreapp3.0</TargetFramework> <AssemblyTitle>MyEnterpriseLibrary</AssemblyTitle> <Product>MyEnterpriseLibrary</Product> <OutputPath>..\bin\$(Configuration)\</OutputPath> </PropertyGroup> <!-- ... --> </Project> 


Mungkin, dalam beberapa proyek yang menggunakan kontrol Windows Forms, Anda juga harus melakukan panggilan ke UseWindowsForms:


 <UseWindowsForms>true</UseWindowsForms> 


Csproj telah mengubah pendekatannya terhadap aliran kompilasi sumber daya. Sebelumnya, format ini memungkinkan Anda untuk menghubungkan file ke sumber daya dan Konten,
dan bahkan dimana.


Sekarang, jika file tersebut dalam beberapa jenis koleksi, maka Anda harus menghapusnya, dan hanya memasukkannya ke dalam grup yang diinginkan.
Berikut adalah kode yang menarik file.json dari koleksi None dan menghubungkannya ke koleksi Resource.



 <ItemGroup> <None Exclude="file.json" /> <Resource Include="file.json" /> </ItemGroup> 


Oleh karena itu, semua file yang bukan sumber harus dihapus dari koleksi None dan terhubung ke sumber daya. Misalnya, seperti ini:



 <ItemGroup Condition="'$(UseWPF)' == 'true' And $(UseWindowsForms) != 'true'"> <None Exclude="**\*.xml;**\*.xsl;**\*.xslt;**\*.txt;**\*.bmp;**\*.ico;**\*.cur;**\*.gif;**\*.jpeg;**\*.jpe;**\*.jpg;**\*.png;**\*.dib;**\*.tiff;**\*.tif;**\*.inf;**\*.compositefont;**\*.otf;**\*.ttf;**\*.ttc;**\*.tte" /> <Resource Include="**\*.xml;**\*.xsl;**\*.xslt;**\*.txt;**\*.bmp;**\*.ico;**\*.cur;**\*.gif;**\*.jpeg;**\*.jpe;**\*.jpg;**\*.png;**\*.dib;**\*.tiff;**\*.tif;**\*.inf;**\*.compositefont;**\*.otf;**\*.ttf;**\*.ttc;**\*.tte" /> </ItemGroup> 


Beberapa baris harus dihapus, karena mereka merobohkan versi framework pada .net framework 4.0.



  Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" 


Di beberapa tempat setelah konversi, entri aneh akan tetap ada yang mencegah kompilasi proyek. Berikut adalah contoh konstruksi tersebut:



 - <ItemGroup> - <EmbeddedResource Include="**\*.resx" /> - </ItemGroup> - <Compile Remove="something.cs"> 


Klien WCF



Jika Anda menggunakan WCF, Anda harus membuat ulang binding. Cara melakukannya dengan benar dapat dibaca di sini: docs.microsoft.com/en-us/dotnet/desktop-wpf/migration/convert-project-from-net-framework#updating-wcf-client-usage



Apa yang tidak mau lepas landas?



Stylecop dan analisis kode.



Beberapa proyek kami menggunakan analisa kode statis. Saat beralih ke edisi MsBuild modern, kolektor secara eksplisit menyarankan untuk menggunakan penganalisis Roslyn baru alih-alih penganalisa kode statis lama.



Saya harus menerjemahkan aturan lama untuk menggunakan paket Nuget Stylecop.Analyzers dan FxCop.Analyzers mengikuti panduan Microsoft ini. .
Jika Anda memiliki beberapa proyek di folder yang berbeda (mono-repositori), maka jauh lebih nyaman untuk meletakkan koneksi penganalisa di Build.props dan mengkonfigurasinya dengan aturan yang seragam.



Inilah yang terjadi:



 - <RunCodeAnalysis>true</RunCodeAnalysis> + <PackageReference Include="FxCop.Analyzers" Version="2.9.4" /> 


File - Anak Yatim



Format csproj lama menyiratkan koneksi eksplisit file .cs. Pada saat yang sama, kadang-kadang ketika mengganti nama atau refactoring file lama dihapus dari csproj, tetapi mereka tidak dihapus secara eksplisit dari sistem file. Dalam format csproj baru, semua file yang ada di folder proyek akan diambil secara otomatis, hanya file yang belum dihapus sebelumnya. Kemungkinan besar akan ada kesalahan di dalamnya, naik banding ke kelas, metode, sumber daya yang sudah tidak ada. Ini akan menghasilkan kesalahan umum selama perakitan.



Sumber daya



Di salah satu proyek, SplashScreen digunakan, salah satunya dipilih secara acak saat startup. Contoh SplashScreen diinisialisasi dengan jalur ke sumber daya. Untuk beberapa alasan, tidak mungkin menang di netcore 3: bersumpah karena kurangnya sumber daya.



Kode yang sepertinya berfungsi



Kode yang berfungsi di .Net Framework kemungkinan akan bekerja di netcore juga. Tetapi mungkin ada bagian kode yang ditutup oleh kompiler. Dalam hal ini, jika kode mendapatkan instruksi yang tidak diimplementasikan dalam netcore, kami akan menangkap PlatformException.


Untuk mencari tempat-tempat seperti itu, ada penganalisa khusus: github.com/dotnet/platform-compat .



Kenapa semua ini jika proyek ini berhasil?



Tidak banyak keuntungan, namun demikian, mereka.



  • Kode Anda akan menerima semua optimasi yang ditambahkan ke netcore.
  • Kecepatan peluncuran aplikasi akan meningkat.
  • Menargetkan versi C # yang akan datang.
  • Mengurangi waktu pembuatan untuk proyek berkat versi csproj yang baru.
  • Packing dalam exe tunggal.


Microsoft tidak mendorong aplikasi ke pijakan baru. Namun demikian, jika aplikasi Anda adalah plugin dari yang lebih besar, maka masuk akal untuk membidik rilis mendatang, yang mungkin juga ada di netcore.



Tautan yang bermanfaat



Source: https://habr.com/ru/post/id470401/


All Articles