【Xamarin】既存のXamarin.FormsプロジェクトにPrism.Unity.Formsをインストールして使うための手順

初めからPrismを使うと決まっていればいいのですが、途中から使いたいとなることもあるかなと思います。個人的に作っているしょぼアプリに勉強ついでにPrismを導入することにしました。修正した部分を記録しておきます。

Nugetで必要なものをインストール

Prism.Unity.Forms を追加

Xamarin.Essentials.interfacesを追加

インストールしようとしたけどエラーが出た。

重大度レベル コード 説明 プロジェクト ファイル 行 抑制状態
エラー NU1605 Xamarin.Essentials の 1.5.3.2 から 1.3.1 へのパッケージ ダウングレードが検出されました。別のバージョンを選択するには、プロジェクトから直接パッケージを参照してください。
LifeTimer -> Xamarin.Essentials.Interfaces 1.5.3.2 -> Xamarin.Essentials (>= 1.5.3.2)
LifeTimer -> Xamarin.Essentials (>= 1.3.1) LifeTimer C:\Users\xiaot\source\repos\Xamarin\LifeTimer\LifeTimer\LifeTimer.csproj 1

Xamarin.Essentials(1.3.1)があるからかエラーがでたのだろう。

削除して再度インストール。するとインストールが成功した。

App.xamlを修正

ソースコードの修正はApp.xamlだけだった。
修正ポイントをピックアップするけど、まずはソースを載せておきます。

App.xaml

<?xml version="1.0" encoding="utf-8" ?>
<prism:PrismApplication xmlns="http://xamarin.com/schemas/2014/forms"
                        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                        xmlns:prism="http://prismlibrary.com"
                        x:Class="LifeTimer.App">
    <Application.Resources>
        <ResourceDictionary>
            <Style TargetType="NavigationPage">
                <Setter Property="HasNavigationBar" Value="True" />
                <Setter Property="BarBackgroundColor" Value="Black" />
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</prism:PrismApplication>

Prism導入前と後の差分は以下のような感じ。

名前空間にxmlns:prism=”http://prismlibrary.com”を追加する。

タグをApplicationからprism:PrismApplicationに変更する。

バーの色を変更する

元は以下のようにしていた。

            MainPage = new NavigationPage(new MainPage())
            {
                BarBackgroundColor = Color.FromHex("#000"),
            };

これを以下のように修正

    <Application.Resources>
        <ResourceDictionary>
            <Style TargetType="NavigationPage">
                <Setter Property="HasNavigationBar" Value="True" />
                <Setter Property="BarBackgroundColor" Value="Black" />
            </Style>
        </ResourceDictionary>
    </Application.Resources>

App.xaml.csを修正

App.xaml.cs

using System;
using System.IO;
using LifeTimer.Data;
using LifeTimer.Views;
using Prism;
using Prism.Ioc;
using Xamarin.Essentials.Implementation;
using Xamarin.Essentials.Interfaces;
using Xamarin.Forms;

namespace LifeTimer
{
    public partial class App
    {
        public App() : this(null) { }

        public App(IPlatformInitializer initializer) : base(initializer) { }

        protected override async void OnInitialized()
        {           
            InitializeComponent();
            await NavigationService.NavigateAsync("NavigationPage/MainPage");

        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterSingleton<IAppInfo, AppInfoImplementation>();

            containerRegistry.RegisterForNavigation<NavigationPage>();
            containerRegistry.RegisterForNavigation<MainPage>();
        }
    }
}

コンストラクタでプラットフォーム固有の依存をDIによって解消している

public App(IPlatformInitializer initializer)の引数が何に使われるのか疑問に思って調べた。こちらで解説されているのですが、プラットフォーム固有の機能を IPlatformInitializer を使って疎結合に使用する仕組みです。