21. Do not go along with breaking changes to libraries
NuGet パッケージ更新時の破壊的変更
• メジャーバージョンアップは、破壊的変更になる場合が多い
ライブラリの破壊的変更によるエラーの修正は厄介なことが多い
.NET 6 移行によるエラーと混在すると解決が困難になる
ライブラリの Upgrade は別の機会でやりましょう
22. Examples of breaking changes in libraries
ライブラリの破壊的変更例
ex: MahApps.Metro
WPF の共通コントロールを Modern UI に上書きするライブラリ
Ver 1.6.5から Ver 2.x へ移行できそう
Webで確認すると
破壊的変更が大量に!
全然わか
らない!
40. .NET Upgrade Assistant
Reduce time and difficulty modernizing
older .NET codebases
Guided, step-by-step experience
Multiple project types supported
C# & VB.NET languages
Supports .NET 6
Learn more: aka.ms/dotnet-upgrade-assistant
41. Projects supported by this tool
.NET Upgrade Assistant の対応フレームワーク
• Windows Forms
• Windows Presentation Foundation (WPF)
• ASP.NET MVC
• コンソールアプリケーション
• クラスライブラリ
今後、もっと増える予定あり
44. Upgrade command
Upgrade コマンドの例
1. Back up project
2. Convert project file to SDK style
3. Clean up NuGet package references
4. Update TFM
5. Update NuGet Packages
6. Add template files
7. Update Winforms Project
a. Default Font API Alert
b. Winforms Source Updater
8. Upgrade app config files
a. Convert Application Settings
b. Convert Connection Strings
c. Disable unsupported configuration sections
9. Update source code
a. Apply fix for UA0002: Types should be upgraded
b. Apply fix for UA0012: 'UnsafeDeserialize()' does not exist
10. Move to next project
Windows From に対して最初に実行
した時に表示される結果 1. Back up project
2. Convert project file to SDK style
3. Clean up NuGet package references
4. Update TFM
5. Update NuGet Packages
6. Add template files
7. Upgrade app config files
a. Convert Application Settings
b. Convert Connection Strings
c. Disable unsupported configuration sections
d. Convert system.web.webPages.razor/pages/namespaces
8. Update Razor files
a. Apply code fixes to Razor documents
b. Replace @helper syntax in Razor files
9. Update source code
a. Apply fix for UA0001: ASP.NET Core projects should not reference ASP.NET namespaces
b. Apply fix for UA0002: Types should be upgraded
c. Apply fix for UA0005: Do not use HttpContext.Current
d. Apply fix for UA0006: HttpContext.DebuggerEnabled should be replaced with
System.Diagnostics.Debugger.IsAttached
e. Apply fix for UA0007: HtmlHelper should be replaced with IHtmlHelper
f. Apply fix for UA0008: UrlHelper should be replaced with IUrlHelper
g. Apply fix for UA0010: Attributes should be upgraded
h. Apply fix for UA0012: 'UnsafeDeserialize()' does not exist
10. Move to next project
ASP.NET Core 2.2 (.NET Framework 4.6.1)に対して
最初に実行した時に表示される結果
共通処理
フレームワーク別の処理
45. How to use the .NET Upgrade Assistant
.NET Upgrade Assistant の使いどころ
ツール頼みでの100%移行は難しい。手動による移行の補助として使うことをおススメ
基本的な移行タスクは全てやってくれる!でも細かいところは手動でやらなければならない
場合も多い
• 依存パッケージ数が多すぎると推移的な依存を削除できずエラーになることがある
• なぜか未対応のフレームワークと判定されて処理してくれないことがある
• ASP.NET Core(MVC)の場合はフレームワークが大幅に変更されているため、ツールによるフレームワーク別の
処理の適用タイミングを計らないと修正箇所が多すぎて大変
ツールがうまく適用できない場合の例
49. Migration policy by framework
フレームワーク別対応方針
• .NET Framework Windows Form / WPF アプリケーション
• .NET Framework ASP.NET MVC アプリケーション
• Xamarin.Form、Xamarin ネイティブ
• .NET Framework コンソールアプリケーション
• .NET Framework クラスライブラリ
• など
コンソールアプリケーションとクラスライブラリは「基本的な移行の流れ」で移行可能。ただし、
Linux など Windows 以外のプラットフォームでも稼働するようにしたい場合は .NET Platform
Compatibility Analyzer で確認すると 「PlatformNotSupportedException 」をスローする API を
使用しているかどうかがわかる
https://docs.microsoft.com/ja-jp/dotnet/standard/analyzers/platform-compat-analyzer
この後説明
50. Windows Form / WPF
Windows Form / WPF の移行
「基本的な移行の流れ」で紹介した通りで移行可能だが、Windows 固有の API を使用してい
る場合は(大抵の場合はそう) Windows 互換性パッケージの参照を加える
※ 移行作業の実際については、Appendixを参照
<ItemGroup>
<PackageReference Include="Microsoft.Windows.Compatibility" Version="6.0.0" />
</ItemGroup>
Windows 互換性パッケージ
https://docs.microsoft.com/ja-jp/dotnet/core/porting/windows-compat-pack
SDK 形式のプロジェクトファイルにこの PackageReferece を追加
51. ASP.NET Core MVC
ASP.NET Core MVC の移行
ASP.NET, ASP.NET Core は バージョン間の破壊的変更が激しいので移行が難しい
ASP.NET MVC 3~5 ASP.NET Core MVC 2.2 ASP.NET Core MVC 3.1 ASP.NET Core MVC 6
そこで、ASP.NET Core MVC 2.2 の特徴を活かす
この移行方法は個人的にお勧めするものです
.NET Framework 4.x
.NET Core 2.2 .NET Core 3.1 .NET 6
ASP.NET Core MVC 2.2 だけが、現在は唯一
.NET Framework も .NET Core でも稼働する
※ただし、.NET Core 2.2 は既にサポートが切れているので、あくまで移行途中に使う
52. Migration Path
移行パス
ASP.NET MVC 3~5
.NET Framework 4.x
ASP.NET Core MVC 2.2
.NET Framework 4.x
.NET Core 2.2
Visual Studio 2017
Visual Studio 2019/2022
.NET Core 3.1
ASP.NET Core MVC 3.1
Visual Studio 2022
.NET 6
ASP.NET Core MVC 6
Visual Studio 2010/2013/2015/2017
ASP.NET Core MVC 2.2
Visual Studio 2017/2019
変更量 大
変更量小~中 変更量 小~中
変更量 小
• ASP.NET Core MVC 2.2 プロジェク
トを作成(SDKスタイル+Package
Reference)し、手動で移行
• 直接参照しているパッケージのみ
をだけを参照するように修正
• Upgrade-AssistantでTFM更新をス
キップして他タスクをすべて処理
• TFMを手動で netcoreapp2.2に変更
• Upgrade-Assistantで全タスク実行
※この移行パスは個人的なお勧めです
• TFMを netcoreapp3.1に変更
53. ASP.NET Core MVC 2.2
VS 2017 だけが作成可能な ASP.NET Core MVC 2.2
SDKを Install する場合は x64 版を
ASP.NET MVC から ASP.NET Core MVC 2.2 への移行
https://docs.microsoft.com/ja-jp/aspnet/core/migration/mvc?view=aspnetcore-2.2
58. .NET – non enabled framework migration
.NET 非対応フレーム
ワークの移行
59. Migration policy by framework
フレームワーク別対応方針
• ASP.NET Web Form
• ASP.NET Web Pages
• WCF サービス(サーバーサイド)
• ワークフローに関連するサービス
• Windows Workflow Foundation (WF)
• ワークフロー サービス (1 つのサービスに WCF と WF) および WCF
Data Services (旧称: ADO.NET Data Services)
この後説明
この後説明
◆ ASP.NET Web Pages は ASP.NET Core Razor Pages が移行先となり得るが、移行に関する情報が
公式にはないため、手動で頑張ることになる。これを機に ASP.NET Core MVC へ移行もアリ
62. ASP.NET Web Form migration
ASP.NET Web Form の移行
• Blazor WebAssembly へ移行する
• ビジネスロジックは、ASP.NET Core ベースの WebAPI にして、Blazor
から WebAPI を呼び出す
表示ロジックは Blazor へ移植する
方法その1
• Blazor Serverへ移行する(ASP.NET Web Formと非常に相性が良い)
方法その2
おすすめ!
要件については要確認
• クライアントのブラウザのバージョンは問題ないか
• ブラウザとの通信に用いられる SignalR で通信可能か
63. Porting to Blazor Server
Blazor Server に移植する
Blazorに移植された Web Form コントロールがある!
オープンソース コミュニティ プロジェクト
https://fritzandfriends.github.io/BlazorWebFormsComponents/
Editor Controls
• AdRotator
• Button
• HiddenField
• HyperLink
• Image
• ImageButton
• Label
• LinkButton
• Literal
Data Controls
• DataList
• FormView
• GridView
• ListView
• Repeater
Validation Controls
• CustomValidator
• RegularExpressionValidator
• RequiredFieldValidator
• ValidationSummary
Navigation Controls
• TreeView
Utility Features
• Databinder
• ViewState
64. Blazor WebForms Components
Blazor WebForms Components
ASP.NET WebForm からの移行についての解説ページがある
ASP.NET WebForms のコントロールほどの機能は持っていないものが多いような
ので、使用にあたってはよく検討が必要
65. Details about porting to Blazor
Blazor に移植する方法の詳細情報
ASP.NET Web Forms 開発者向け Blazor
https://docs.microsoft.com/ja-jp/dotnet/architecture/blazor-for-web-forms-developers/
116. Information about the Xamarin native migration
Xamarin ネイティブの移行の情報
https://github.com/dotnet/maui/wiki/Migrating-from-Xamarin.Forms-(Preview)
Only works with Xamarin.Forms .slns
(Xamarin.Android and Xamarin.iOS only solutions
coming later)
Xamarin ネイティブ向けの移行情
報が公開される予定
128. Reconstruct service class
サービスクラスを再実装
public override async Task<GetAllResponse> GetAll(GetAllRequest request, ServerCallContext context)
{
if (!Guid.TryParse(request.TraderId, out var traderId))
{
throw new RpcException(new Status(StatusCode.InvalidArgument, "traderId must be a UUID"));
}
var portfolios = await _repository.GetAllAsync(traderId);
var response = new GetAllResponse();
response.Portfolios.AddRange(portfolios.Select(Portfolio.FromRepositoryModel));
return response;
}
}
}
using Grpc.Core;
using TraderSys.PortfolioData;
using TraderSys.Portfolios.gRPC;
using TraderSys.Portfolios.Protos;
namespace TraderSys.Portfolios.gRPC.Services
{
public class PortfolioService : Protos.Portfolios.PortfoliosBase
{
private readonly ILogger<PortfolioService> _logger;
private readonly IPortfolioRepository _repository;
public PortfolioService(ILogger<PortfolioService> logger, IPortfolioRepository
repository)
{
_logger = logger;
_repository = repository;
}
public override async Task<GetResponse> Get(GetRequest request, ServerCallContext
context)
{
if (!Guid.TryParse(request.TraderId, out var traderId))
{
throw new RpcException(new Status(StatusCode.InvalidArgument, "traderId
must be a UUID"));
}
var portfolio = await _repository.GetAsync(traderId, request.PortfolioId);
return new GetResponse
{
Portfolio = Portfolio.FromRepositoryModel(portfolio)
};
}
リポジトリから取得したPOCOオブジェクトを
gRPC の扱う Protobuf のクラスに詰め替え直す
Standard2.0に移行したクラスライブラリをプロジェクト参照
129. Set up Dependency Injection
Dependency Injectionを設定
using TraderSys.PortfolioData;
using TraderSys.Portfolios.gRPC.Services;
var builder = WebApplication.CreateBuilder(args);
// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit
https://go.microsoft.com/fwlink/?linkid=2099682
builder.Services.AddScoped<IPortfolioRepository, PortfolioRepository>();
// Add services to the container.
builder.Services.AddGrpc();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.MapGrpcService<PortfolioService>();
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client.
To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
app.Run();