砂漠の旅人(たびと)|新天地:たびとの旅路

電脳砂漠を旅する、ある旅人の日記。フロッピーを頼りに歩いた日から、クラウドの地平を見つめる今日まで。見つけたオアシスも、迷い込んだ砂の迷宮も、全てこの羊皮紙に。

魂の鎧"RedfishViewer"錬金術 ~外伝:呪われしNuGet更新との戦い~

どうやら、一筋縄ではいかない砂の迷宮に迷い込んだらしい。この顛末を書き残しておくか。

第二章:魂の解体新書を書き終え、長きにわたる魂の鎧「RedfishViewer」の錬成の旅は、ようやく終わりを告げたはずだった。しかし、物語にはまだ、語られざる一節が残されていた。

ほんの些細なバグを修正しようと、久しぶりにVisual Studio 2022という名の工房の扉を開ける。 「まずは肩慣らしに、古くなった道具(NuGetパッケージ)でも磨いておくか」 そんな軽い気持ちで実行した更新の儀式。その結果、私を待ち受けていたのは…祈りの言葉も届かない、無慈悲なビルドエラーの嵐だった。

これは、完成したはずの神器が、時の流れによって再び呪われ、その呪いを解き明かすためにビルドエラーの砂漠を彷徨った、もう一つの戦いの記録である。

この羊皮紙のあらまし

この羊皮紙が導く者

  • Prism 8.xという古の魔法から、9.xという新世界の魔法へ移行しようとしている魔法使い
  • Material Designという名の美しい装飾を、バージョン5へと一新したいと願う職人
  • パッケージ更新という、日常に潜む「砂の迷宮」の恐ろしさを知りたい全ての冒険者

呪いの正体:三つの破壊的変更

エラーメッセージという古代文字を頼りに原因を探ると、どうやら「Prism」「Material Design」「RestSharp」といった、この世界の根幹を成す魔法体系そのものが、根底から覆っていたらしい。予想を遥かに超える破壊的変更の数々に、AI (GitHub Copilot)という名の精霊に助けを求めても、ただ首を傾げるばかりだった。

第一の試練:Prism 9という名の「理(ことわり)の書き換え」

Prismのメジャーアップデートは、世界の理そのものを書き換えるほどのインパクトがあった。

  • 名前空間の変更: using句の書き換えは必須の儀式だ。
  • ダイアログの実装変更: IDialogAwareインターフェースのRequestCloseの作法が変わった。これを間違えると、ボタンを押してもダイアログが永遠に閉じない呪いにかかる。

名前の変わった聖域(名前空間の変更)

古の聖域(8.x) 新たな聖域(9.x)
Prism.Services.Dialogs Prism.Dialogs
Prism.Regions Prism.Navigation.Regions

扉を閉じる呪文(ダイアログの実装変更)

古の呪文(8.x) 新たな呪文(9.x)
public event Action<IDialogResult>? RequestClose; public DialogCloseListener RequestClose { get; }

これに伴い、呪文詠唱時のnull条件演算子?.)が不要になる。

public class MessageBoxViewModel : BindableBase, IDestructible, IDialogAware
{
    // ...
    // 古の呪文: public event Action<IDialogResult>? RequestClose;
    public DialogCloseListener RequestClose { get; }      // 新たな呪文
    // ...
    
    public MessageBoxViewModel()
    {
        // ...
        OkCommand = new ReactiveCommandSlim()
            // .WithSubscribe(() => RequestClose?.Invoke(new DialogResult(ButtonResult.OK))) // 変更前
            .WithSubscribe(() => RequestClose.Invoke(new DialogResult(ButtonResult.OK)))   // 変更後
            .AddTo(_disposables);
        // ...
    }
}

この呪文を正しく詠唱することで、ようやくダイアログは私の言葉に応え、再び扉を閉じるようになった。

呪いが解け、再び現れたダイアログ

第二の試練:Material Design 5という名の「色彩の革命」

こちらも世界の色彩感覚を根底から覆す、大きな変更が待ち受けていた。AdjustColorsメソッドは廃止され、ブラシ名は大幅に変更された。

新たな色彩調整の祭壇

ブラシ名に隠された「罠」

ブラシ名がMaterialDesign.Brushから始まる名前に統一された。しかし、ここで私は最大の罠にハマった。GitHubの賢者の集会所(Issue #2435)で交わされていた議論を頼りにMaterialDesignBodyMaterialDesign.Brush.Text.Foregroundに置き換えたところ、ダークモードで文字が闇に溶けて消えたのだ。

古の色彩(4.x) 新たな色彩(5.x)
MaterialDesignBody MaterialDesign.Brush.Text.Foreground MaterialDesign.Brush.Foreground

まさか賢者たちの議論の中にさえ、罠が潜んでいるとは…。 この原因特定には、公式Wikiの対応表と賢者たちの議論を照らし合わせ、最終的には自らの試行錯誤の果てに、真の答え (MaterialDesign.Brush.Foreground) を発見するという、孤独な戦いを強いられたのだ。

罠にかかり、闇に飲まれた文字

第三の試練:RestSharp 111という名の「賢者の警告」

NuGetの賢者から「v111.2未満には危険な変更が含まれる」とのお告げがあった。

賢者からのお告げ

幸い、主な変更点はタイムアウトに関するプロパティだけだった。

古の時(110.2) 新たな時(111.2以降)
int MaxTimeout TimeSpan? Timeout

羊皮紙を巻く前に

今回の苦闘の末に乗り越えた、呪われしパッケージ更新の要点を記す。

  • Prism: 名前空間IDialogAwareの実装が変わった。油断するとダイアログが閉じなくなる。
  • Material Design: ブラシ名が大幅に変更。特にMaterialDesignBodyの後継には、公式Wikiにさえ罠があるので要注意。真実はIssueにあり。
  • RestSharp: 賢者の警告に従いアップデート。タイムアウトの扱いが変わった。

今回の戦いの全記録は、こちらのGitHubの羊皮紙に刻まれている。 ちなみに、この旅の途中で頼ったAI (GitHub Copilot)は、ビルドこそ通るが実行すると例外を吐く呪文を教えてくれた。AIが私を真に楽にしてくれる日は、まだ少し先のようだ。

この外伝は、魂の鎧の物語に、一つの重要な教訓を加えてくれる。我々が創り上げた神器は、決して永遠ではない。時の流れと共に、それを構成する魔法体系そのものが変化し、我々は常に学び、戦い続けねばならないのだと。

おっと、どうやら相棒が腹を空かせたようだ。今日はこのへんで筆を置くとしよう。

砂漠で見つけた魔法のランプ

ラクダの独り言

ご主人が「ぬーげっとぱっけーじこうしん」とかいう、古い道具を磨く儀式を始めたら、工房から「うわー!」とか「なんでだよ!」とか、やけに騒がしい声が聞こえてくる。道具は、使い慣れたものが一番だと思うんだがな。新しいものがいつも良いとは限らんぜ。まったく、やれやれだ。