XAMLとコンパイルについて(Xamarin Forms)
あけましておめでとうございます。
今年も「自分の知識の整理」と「技術者としてのフェアの精神(ネットで教えてもらうだけでなく、自ら知り得た知識を共有する精神)」でブログを書いていこうと思います。
また、今年は勉強会とかにも積極的に顔を出してみようかな・・・とか思いつつ・・・
ということで、早速今回はXamarin Formsにおける小ネタを・・・
XAMLとコンパイル
Xamarin Formsで開発を行う場合、UI定義はXAMLで行います。
UI定義以外のロジック(これはコードビハインドにベタ書きするものから、Prismなどのフレームワークを使ってOOに責務を分担したコードまで含めて)は C#言語 で記述します。
XAML と コードを記述し、ビルドメニューを選択するとコンパイル作業が行われ 各DLL が出力されます。このDLLはアセンブリと呼ばれる、.NETにおけるIL(Intermidiate Language)モジュールになります。この辺りは、.NETについてある程度精通している方ならご存知かと思います。C#実装は当然 IL に変換されます。
一方、XAMLはデフォルトでは「リソース」としてDLL内に埋め込まれます。そして実行時にXAML→ILへのコンパイルが行われます(補足として、実行する上では、最終的にはネイティブコードに変換)。
XamlCompilation属性
結論としては、「XamlCompilation属性」というものを用いるとXAMLをビルド時にコンパイルすることが可能になります。
以下、順を追って説明いたします。
コンパイル後のXAMLを確認する
ではまずは、デフォルトの「ビルド時にはXAMLをコンパイルせず、実行時にXAMLがコンパイルされる方式」について確認してみます。
①ソリューションの準備
以下のようなウィザードが生成した単純なXamarin Formsソリューションを用意します。
Xamarin FormsのPCLプロジェクトは「CompExample1」です。
CompExample1Page.xamlの定義は以下とします。Labelを2つ配置した単純なXAML定義です。
<?xml version="1.0" encoding="utf-8"?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:CompExample1" x:Class="CompExample1.CompExample1Page"> <Label Text="Welcome to Xamarin Forms!" VerticalOptions="Center" HorizontalOptions="Center" /> <Label Text="test" /> </ContentPage>
②ビルド
ビルドを行います。
CompExample1/bin/Release/CompExample1.dll が出力されます。
これを ILSpy で逆コンパイルしてみましょう。
結果は以下です。
Resources配下に 対象XAMLがそのまま埋め込まれていることが確認できます。
また、フォームのコードビハインドコード内の InitializeComponent() 中で LoadFromXaml() によりXAMLリソースをロードしています。
XAMLを開発時にコンパイルする(XamlCompilation属性)
次に XamlCompilation属性 を使用してみます。
ソリューションは先程の CompExample1 を使用します。
①XamlCompilation属性の付加
XamlCompilation属性は「アセンブリ(アプリケーション)単位」もしくは「フォーム単位」で指定することができます。
アセンブリ単位の指定には、以下のように名前空間に対して「[assembly: XamlCompilation(XamlCompilationOptions.Compile)]」属性を付加します。
// アセンブリ単位に指定(App.xaml.cs) using Xamarin.Forms; using Xamarin.Forms.Xaml; [assembly: XamlCompilation(XamlCompilationOptions.Compile)] namespace CompExample1 { public partial class App : Application { ... } ... }
フォーム単位の指定には、以下のようにコードビハインドクラスに対して「[XamlCompilation(XamlCompilationOptions.Compile)]」属性を付加します。
// フォーム単位に指定(CompExample1Page.xaml) using Xamarin.Forms; using Xamarin.Forms.Xaml; namespace CompExample1 { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class CompExample1Page : ContentPage { public CompExample1Page() { InitializeComponent(); } } }
②ビルド
ビルドを行います。
先程と同様にCompExample1/bin/Release/CompExample1.dll を ILSpy で逆コンパイルしてみましょう。
結果は以下です。
Resourcesが無くなりました。
そして、コードビハインドクラスの InitializeComponent() 内にXAMLで定義したUIを構築するためのコードが追加されています。つまり、XAMLはコードに変換され、ILとなりDLLアセンブリに格納されました。
開発時コンパイルのメリット
XAMLを開発時にコンパイルすると以下のようなメリットがあります。
1) コンパイル時にXAML構文チェックが行われる
例えば以下のようにXAML構文上のエラーがあった場合、XamlCompilation属性を使用していないとビルド(コンパイル)は正常終了してしまいます。そして実行時にエラーとなります。
開発ビルド時に構文チェックが行われることで、開発生産性の向上が見込まれます。
... 省略 <Label Content="test" /> ← WPFは Content でOKでしたが、Xamarin Formsでは Text ですね。 ... 省略