WCF を.NET Native で使用する方法

 

本記事は、マイクロソフト本社の .NET Framework Blog の記事を抄訳したものです。 【元記事】Using WCF in .NET Native  28 Aug 2014 1:38 PM

※本記事はWCFチームのソフトウェア開発エンジニアである Ron Cain が執筆しました。

以前の投稿で、Visual Studio "14" CTP3 において、Windows Communication Foundation (WCF) のいくつかのクライアント機能が .NET Native Windows ストア アプリでも使用できるようになったことをご紹介しました。今回は、CTP3 でのサンプル WCF Windows ストア アプリのビルド方法と、それをどうやって.NET Nativeでコンパイルするかをご説明します。

なお、今回お話しすることの大部分は、.NET Native だけではなく、従来の Windows ストア アプリにも同様に適用できます。最後のセクションでは、.NET Native を使用する場合のいくつかの追加手順を説明しています。

まず初めに、https://support.microsoft.com/kb/2967191 から Visual Studio "14" CTP3 をインストールしてください。

.NET Native について詳細をお知りになりたい場合には、.NET Native プレビュー版についてのこちらのブログポスト をご覧ください。

 

アプリのテスト用に、IISをホストとする WCF サービスを作成する

Windows ストア アプリ作成を始める前に、それに使用する WCF サービスが必要です。また、Windows ストア アプリは localhost に接続することができないため、このサービスのためのホストが必要になります。今回のサンプルでは、プライベートの開発マシン上での IIS を使用することにします。

 

IISを有効にする

[コントロール パネル] を検索し、[プログラムと機能] から [Windows の機能の有効化または無効化] をクリックします。 [Internet Information Services]にチェックを入れてマシンの IIS を有効にします 。

 

WCF サービスを作成する

IIS をサービスのホストとして設定するため、管理者として Visual Studio を開く必要があります。まず、WFC アプリケーションの新しいプロジェクトを開きます。

このサービスはすぐに使えて機能も揃っていますが、少し使いにくいため、少々設定を変えます。作成したWFDのサービス コントラクト(IService1.cs)に、新たに SayHello() メソッドを追加します。これを [OperationContract] としておくことで、WFC クライアントからこのメソッドを呼び出すことができます。

さらに、この新たなインターフェイスのメソッドを実装する必要もあるので、作成したサービスの実装クラスのコード (Service1.svc.cs) を追加します。

7762.Picture_04

これでWCFサービスの準備ができました。あとはこのサービスのホストを設定するだけです。ソリューション エクスプローラーの [MyWCFService] を右クリックし、プロパティのウインドウを開きます。Webタブで [Local IIS] を選択してください。これで、この開発マシン上の IIS がWCFサービスのホストとして設定されます。

最後に、保存する際に仮想ディレクトリの作成を要求されます。ここで「はい」を押せば、IIS がサービスのホストとなります。

サービスが有効になっているかどうかを確認するには、Service1.svc を右クリックして、 [View in Browser] を選択してください。下記スクリーンショットのような画面が出れば、IIS が正常に作動し、使用できる状態です。後の操作で必要になりますので、この URL を控えておいてください。

このURL を別のマシンで試してみるとよいでしょう。その際は localhost 部分をそのマシン名に変更してください。もし必要であれば、他マシンのWindows
や Firewallでの World Wide Web Services (HTTP) を承認してください。Windows ストア アプリからは、このマシン名のURLが使えます。

 5751.Picture_07

WCF Windows ストア クライアント アプリケーションを作成する

WCFサービスの設定が完了しました。次に Windowsストア クライアントを作成しましょう。ここではまず、従来のWindows ストア アプリ を作成します。次のセクションで、それに .NET Native を適用させてみましょう。

まず、[Blank App] で新しいWindows ストアのプロジェクトを作成します。同じ開発マシンを使っても、別のマシンでも構いません。ここでは、意図せずlocalhost に依存することのないように、別のマシンを使って作成することにします。

下記が生成されたプロジェクトです。

作成したWCFサービスへリンクさせるには、ソリューション エクスプローラーの [reference] を右クリックして、[Add Service Reference] を選択してください。アドレスのフィールドに、サービスの閲覧に使う URL を入力します。Windows ストア アプリは localhost には接続できないため、IIS を設定したマシン名のURL を使う必要があります。[Go] を押し、Service1 を選択し、[OK] を押してください。[Namespaces] に関しては、この投稿のコードをペーストできるように、デフォルトのままにしておくことをお勧めします。

[Add Service Reference] を使用することで、WCFサービスに適用できるコードが生成されるようになっています。このコードは通常隠れていますが、確認したい場合には、ソリューション エクスプローラーの  [Show All Files] をクリックし、Reference.cs. を開いてください。

外部のWCFサービスに接続するには、アプリがそのネットワークへアクセスする必要があります。[Capabilities] タブにある Package.appxmanifest をダブルクリックし、 [Internet and Private Network] のチェックボックスにチェックをしてください。

ストアアプリにUIを追加してみましょう。ここでは、[MainPage.xaml] をダブルクリックし、ツールボックスから二つのテキスト ボックスとボタンをドラッグします。プロパティ ペイン (F4) を使って、それぞれを TheInputBox、TheOutputBox、TheButton とリネームしてみました(…言い訳ですが、私はデザインやネーミングはどうも苦手です)。

TheButton のテキストを変更し、さらにそれをダブルクリックしてハンドラ―を作成しました。皆さんが内容を比較したいかもしれませんので、下記に私のグリッド用XAMLコードを載せておきます。

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBox x:Name="TheInputBox" HorizontalAlignment="Left" Margin="203,197,0,0" TextWrapping="Wrap"
Text="TextBox" VerticalAlignment="Top" Height="31" Width="164" />
<TextBox x:Name="TheOutputBox" HorizontalAlignment="Left" Margin="203,300,0,0" TextWrapping="Wrap"
Text="TextBox" VerticalAlignment="Top" Height="28" Width="164" />
<Button x:Name="TheButton" Click="TheButton_Click" Content="Call WCF service"
HorizontalAlignment="Left" Margin="200,244,0,0" VerticalAlignment="Top" Width="170" />
</Grid>

通常のWindows ストア アプリ作成にあと必要なのは、ボタンをつなぐことだけです。TheButton の [View code] から、下記のコードを加えてください。

private async void TheButton_Click(object sender, RoutedEventArgs e)

{
var client = new ServiceReference1.Service1Client();
TheOutputBox.Text = await client.SayHelloAsync(TheInputBox.Text);
}

このコードについて少し解説しましょう。

ServiceReference1.Service1Client は、[Add Service Reference] によって生成された隠れファイル Reference.cs の中にあります。SayHelloAsync() は、このWCF サービスの SayHello() メソッドを実行するために生成されたメソッドです。末尾の Async は、このメソッドが非同期であり、[Task] を返すことを表しています。このコード内で Service1Client が作成され、SayHelloAsync() を呼び出し、それが返す [Task] に対し [await] を適用します。ここではUI スレッドをブロックしないように [await] を使用しています。[await] を経由して得られた [Tasks] の結果は、サーバーから返されたバリューです。await を使用するには、TheButton_Click メソッドのシグネチャに async を追加する必要があります。長くなりすぎるので、例外処理については割愛します。

この段階で、従来のWindows ストアアプリ作成は完了です。ただし、このサンプルの目的は、従来のWindows ストア アプリを.NET Native appに適用することですから、もう少し先を続けましょう。

 

最後のステップ- アプリで.NET Nativeを使用する

まず、特定のアーキテクチャに対しては、設定を [Any CPU] から変更する必要があります。これは .NET Native でも必要です。このサンプルでは、x64 を使うことにしましょう。

次にプロジェクトを右クリックし、[Enable for .NET Native] を選択します。

 

このプロパティ設定により、このプログラムの.NET Native との互換性が分析され、問題が特定されるとレポートが作成されます。このサンプルでは、レポートが作成されても問題は検出されないはずです。

最後のステップは、このアプリケーションを .NET Nativeアプリとしてビルドするための設定です。プロジェクトを右クリックし、プロパティを選択し、[Build] タブにある [Compile with NET Native tool chain] にチェックを入れてください。

これで完了です。アプリは使用できる状態になっています。ビルドの際には.NET Native でのコンパイルが可能です。

アプリをテストするには、デバッガー (F5) を起ち上げ、名前を入力してください。ボタンを押すと、WCF サービスから返答があります。下記がその返答です。外部の WCF サービスで実行可能な .NET Native からリクエストを送り、無事に返答を得ました。

5633.Picture_17

 

次のステップ

このサンプルアプリを使用して、例えば複雑な DataContract タイプを交換してみたりして、ぜひホステッド WCF サービスのインターフェイスをより面白いものに変えていってください。サービスとクライアント間のパブリックなインターフェイスを変更するには、サービス参照をクリックして [Update Service Reference] を選択してください。これにより、WCF サービスに接続し、新たなサービスコントラクトを取得し、生成されたコードの更新ができます。

 6201.Picture_18

トラブルシューティング

今回ご説明した .NET Native でのWCFは、まだかなり初期段階のため、問題が起こる可能性もあります。私が遭遇したそういった問題の一つと、それをどう解決したかをご紹介します。

.NET Native Windows ストア アプリを、これまでご説明してきた通りの手順でビルドした際、実験的に[Add Service Reference] で [Virtual Earth] を適用してみました。起動しようとしたところ、クライアント作成で InvalidOperationException という問題が起きました。 デバッグによると、このアプリは WCF の FaultContractAttribute を使用しており、残念ながら、CTP3 では FaultContractAttribute に対するリフレクションができていませんでした。

対応策は、そのタイプには、アプリ自体によるリフレクションを行うということです。アプリ内の default.rd.xml というファイルは .NET Native コンパイラーの Runtime Directives を含んでいます。このファイルのスキーマについては、こちらで詳細とサンプルをご覧いただけます。

このケースでは、そのファイルを下記のように編集し、「このアプリは “System.ServiceModel.FaultContractAttribute” でリフレクションを使用する必要がある」と書き換えました。この変更により、問題は起こらなくなりました。

 

まとめ

今後のリリースで、引き続き .NET Native 向けWCF の安定化と機能向上を進めていきます。これからも、追加機能やより多くのサンプルをご紹介していく予定です。皆さんからのご意見、特にどんな機能が望ましいか、なぜそれが必要なのかについて、ぜひアイデアをお寄せいただければと思います。

.NET Native 向けWCFのデベロッパーエクスペリエンスに関するフィードバックをお待ちしています。この投稿へコメントいただくか、dotnetnative@microsoft.com へ英文にてメールをお送りください。