きよくらの備忘録

「三日坊主と呼ばせない!日記」改め。主にソフトウェア開発関連の話題。

WCFとの連携を試してみたその(2)

上の続きです。いよいよ、Silverlight側からサービス参照を行って、データを受け取ってみます。

5.Silverlightにサービス参照でWCFのサービスへの参照を追加

先ほど作ったサービスへの参照を追加します。ここはほとんどウィザード任せでいろいろやってくれるので、楽といえば楽。

[1]サービス参照ウィザードの起動

ソリューションエクスプローラのコンテキストメニューの[サービス参照の追加]等から、ウィザードを起動します。

[2]サービスの探索と確定

同一ソリューション内のサービスを追加する場合は、ダイアログの左側らへんの[探索]ボタンをクリックして表示される[ソリューションのサービス]をクリック。「サービス」欄にService1.svcが出てくるので、それを選択して[OK]。今回は、例によって面倒なので名前空間は既定のServiceReference1のまま変えていません。
終了すると、Service Referencesの下にServiceReference1というのができて、ファイルをすべて表示する設定にすれば、ServiceReference1の下にいろいろ追加されているのが解ります。やり取りするデータ型のxsdファイルとかもできてる模様。

6.Silverlightでサービスを呼び出すコードをかく

ただコードを書くとか言ってもアレなんで、とりあえずボタンひとつとテキストボックス二つ置いて、ボタンクリックで先ほどのメソッドが返すHogeDataのメンバの値を表示させる、ということで。

[1]Page.XAML

Page.XAMLは以下のような感じで。横着もいいところですけれど。

<UserControl x:Class="SilverlightApplication.Page"
    xmlns="http://schemas.microsoft.com/client/2007" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="400" Height="300">
    <Canvas Background="AliceBlue">
        <Button Click="Button_Click" Canvas.Top="10" Canvas.Left="20" Width="200" Height="20" Content="クリック Me!"></Button>
        <TextBox x:Name="TextBox1" Canvas.Top="40" Canvas.Left="20" Width="200"></TextBox>
        <TextBox x:Name="TextBox2" Canvas.Top="70" Canvas.Left="20" Width="200"></TextBox>
    </Canvas>
</UserControl>
[2]Page.XAML.vb

Page.XAML.vbは以下のような感じで。
ServiceReference1.Service1Clientの入れ物である変数clientは、クラスのプライベートフィールドとして作っておいて、コンストラクタインスタンス化します。ついでに、コンストラクタで非同期実行完了時のコールバックをイベントハンドラとして登録してやります。このあたりは普通にVBイベントハンドラを追加するのと同じ要領。

Partial Public Class Page
    Inherits UserControl

    Private client As ServiceReference1.Service1Client

    Public Sub New()
        InitializeComponent()
        client = New ServiceReference1.Service1Client()
        AddHandler client.GetHogeDataCompleted, AddressOf OnCompletedDataHoge
    End Sub

    Private Sub OnCompletedDataHoge(ByVal sender As Object, ByVal e As ServiceReference1.GetHogeDataCompletedEventArgs)
        Dim resData As ServiceReference1.HogeData
        resData = e.Result
        Me.TextBox1.Text = resData._HogeName
        Me.TextBox2.Text = resData._HogeID
    End Sub

    Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
        client.GetHogeDataAsync()
    End Sub

End Class

本当は、XAMLにはバインドするように書いてやるのが一番良さそうですね。
サービス参照時に自動で作成されるReference1.vbを見てみると、HogeDataのクラスはINotifyPropertyChangedの実装になっていて、プロパティに値がセットされた時にちゃんとRaisePropertyChangedするように書かれていますし。

7.そして実行

これで実行すると、テキストボックスにそれぞれ値が表示されます。めでたしめでたし。あ、当然ながら先ほどWCFのサービスのテストをするためにスタートページを変更していた場合は、SilverlightApplicationTestPage.aspx等のSilverlightの呼び出しが書かれているやつに変更してから実行する必要があります。

8.まとめ、みたいなもの

とりあえずここまでの実験で、

  • WCFのサービスをサービス参照から自動生成したものを使って使える
  • こうすると、Guthrieのチュートリアルにあるような方式でXMLを自力でパースしなくても、自分で作ったクラスを直接(?)使える

事がわかったので、現時点では満足。今後のアップデートでwsHttpBindingやらも使えるようになってくるでしょうし、他にもいろいろ機能が実装されるでしょうし。

ただ一点気になったのは、この自動で作成されるクラス、元のWCFのサービスの方で定義していたプロパティはガン無視されて、プライベートのフィールドの方で直接作れていますね(上のコード中のresData._HogeNameの通り)。VBだと関係名ですけど、C#で自動プロパティを使ったときはどうなるんだろう。まあ、これはSilverlight云々ではなくて、WCFの使い方か作り方が悪いかそもそもそういうものなのか、ってところだと思うので、おいおいWCFの勉強をしていきます。はい。


とりあえずはWCFでデータを取得するのは満足したので、次は分離ストレージとかローカルファイル書き込みについて調べてみようかなぁ、と思います。