かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

Prism.Forms.Unity を .NET Standard プロジェクトにしてみよう(無理やり感)

Xamarin.Forms 2.4 が .NET Standard 2.0 化したこともあり .NET Standard の機運が高まってまいりました。 Prism のほうも 7.0.0 で .NET Standard 対応っぽいのでいい流れです。

最近のライブラリは .NET Standard 前提で作られてるものもチラホラ出てきてるので対応が進んでくれるのは嬉しいですね。

Prism.Forms のプロジェクトの .NET Standard への変換

ということで、現状の Prism Template Pack で新規作成されたプロジェクトとベースに .NET Standard にしてみようと思います。 まず、Prism Template Pack でプロジェクトを新規作成します(NETStdPrismApp という名前でここでは作りました)。現時点では Android, iOS をターゲットにします。何故かというと Xamarin.Forms が .NET Standard 2.0 を対象としているためです。UWP は Fall Creators Update 以降で .NET Standard 2.0 対応ということなので、現時点ではまだ使えないためです。しょんぼり。

新規作成したら、さっそく .NET Standard のクラスライブラリのプロジェクトを追加しましょう。NETStdPrismApp.NETStandard という感じの名前で作りました。Class1.cs をさくっと消して NETStdPrismApp.NETStandard のプロパティを開きます。ターゲットフレームワークを .NET Standard 2.0 にして規定の名前空間を NETStdPrismApp あたりにしておきます。

f:id:okazuki:20171003130613p:plain

移植可能のプロジェクトから packages.config 以外のファイルをまるっとコピーします。 そして、移植可能のプロジェクトを右クリックからアンロードしておきましょう(消すのはうまく動くようになってからのほうが精神衛生上いいので)Droid と iOS プロジェクトから .NET Standard のプロジェクトを参照に追加します。ついでに、移植可能のプロジェクトを Droid と iOS プロジェクトから削除しておきましょう。

ソリューションの NuGet パッケージの管理を開きます。開いたらプレリリースを含めるにチェックを入れて Prism.Unity.Forms v7.0.0-pre1 を選択して Droid, iOS, .NET Standard のプロジェクトに追加します。私はここで Visual Studio の再起動を求められたので再起動をしました。

NuGet パッケージマネージャーからプレリリースを含めるのチェックを外して Xamarin.Forms の最新版(現時点で 2.4.0.282 でした)を全プロジェクトに追加します。私はここでまた Visual Studio の再起動を求められました。

App.xaml, MainPage.xaml が EmbeddedResource として csproj ファイルに追加されてるのをさくっと消します。

  <ItemGroup>
    <EmbeddedResource Include="App.xaml">
      <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
    </EmbeddedResource>
    <EmbeddedResource Include="Views\MainPage.xaml">
      <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
    </EmbeddedResource>
  </ItemGroup>

あと、プロジェクトの下にあるファイルは一定のルールで勝手に追加してくれるみたいなので、MainPage.xaml.cs や App.xaml.cs に関する記述も消してOKっぽいですね。

ここで、やっとビルドが通るようになります。 実行すると…

f:id:okazuki:20171003143236p:plain

動いた!!やったね!

警告!!(未解決)

動いたけど警告が出てますね。 こういうのは .NET Portability Analyzer を使ってチェックすることが出来ます。

docs.microsoft.com

とりあえず exe をダウンロードして適当な場所に配置します。ソリューションエクスプローラを見る限りだと Unity と CommonServiceLocator が警告のおおもとなんですかね?C:\Users\[ユーザー名]\.nuget\packages\commonservicelocator\1.3.0\lib\portable-net4+sl5+netcore45+wpa81+wp8 あたりに dll があるので、そこで以下のコマンドを打ち込みました。

apiport.exe analyze -f Microsoft.Practices.ServiceLocation.dll
Microsoft (R) API Portability Analyzer v1.4.0.alpha.00199
Copyright (C) Microsoft Corporation. All rights reserved.

This tool analyzes .NET assemblies to determine possible problems moving between .NET platforms (such as
Windows Store, desktop, Mono, .NET Core, etc) as well as between .NET Framework versions (ie 4.x->4.y).

To learn more about how this tool works, including the data we are collecting,
go here - http://go.microsoft.com/fwlink/?LinkId=397652

Detecting assembly references                     [Done]
Analyzing compatibility                           [Done]
Writing Excel report                              [Done]

Wrote output to file:

Excel 形式のレポートが出てくるので見てみると大丈夫そうですね。

f:id:okazuki:20171003160612p:plain

Unity も同じ感じでレポートを出してみると、こっちはダメな感じっぽいですね。

f:id:okazuki:20171003161608p:plain

まぁ動いたし警告気にしないで無視るかと思って Prism.Unity.Forms の NoWarn の項目に NU1701 を入れたのに警告が消えない。ふむ。Prism.Unity.Forms じゃなくて、その依存先の警告は消してくれないのかな?消し方がわからん…。プロジェクトレベルで警告を無視することはできるみたいだけど、それはやりすぎ感ですしね。