WCF はじめの一歩

今更ながらWCF(Windows Communication Foundation)を始めた。

長い間プログラミングから遠ざかっていた*1ので、若干書き方を忘れてきたけど思い出しつつ勉強開始
まずは基本中の基本からやってみる。

概要

イメージとしてはこんな感じ

Server側とClient側でContract(インターフェース)を決めてあげれば、通信部分のプロトコルとかなんやらはWCFがやってくれまっせという事です。

これに従って、今回作成するプロジェクトは以下の三種類

  • WcfService(コンソール)
  • WcfServiceInterface(ライブラリ)
  • WcfClient(コンソール)

また、参照設定に以下のアセンブリを追加しておく

  • System.ServiceModel(WCFの本体)
  • System.Runtime.Serialization

Contractの定義

まずはインターフェースの定義から

やり取りするデータの型をまずは決める。

WcfServiceInterface/Customer.vb
<DataContract(Namespace:="http://www.coma2n.com/wcfservice/customer")> _
Public Class Customer

    Private m_name As String
    <DataMember()> _
    Public Property Name() As String
        Get
            Return m_name
        End Get
        Set(ByVal value As String)
            m_name = value
        End Set
    End Property

End Class

簡単にNameというプロパティを持つCustomer型を定義する。

WCFを使ってやり取りするデータの型はDataContract属性でマークする必要がある。同様にプロパティはDataMember属性でマークする必要がある。

次は実際にこの型をやり取りするサービスのインターフェースを定義する。

WcfServiceInterface/IWcfService.vb
<ServiceContract(Namespace:="http://www.coma2n.com/wcfservice")> _
Public Interface IWcfService
    <OperationContract()> _
    Function GetCustomer() As Customer
End Interface

インターフェースの定義はこれで終わり。

Server側の実装

Server側では、まずサービスの実装を定義する。

WcfService/WcfServiceImpl.vb
Public Class WcfServiceImpl
    Implements IWcfService

    Public Function GetCustomer() As Customer Implements IWcfService.GetCustomer
        Return New Customer With {.Name = "Ozzy Osbourne"}
    End Function
End Class

こんだけ、後はこれをサービスとして公開する。

まずは、アプリケーション構成ファイルにendpointを定義する。

App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <services>
            <service name="WcfService.WcfServiceImpl">
                <endpoint
                    address="net.tcp://localhost:8081/wcfService"
                    binding="netTcpBinding"
                    contract="WcfServiceInterface.IWcfService" />
            </service>
        </services>
    </system.serviceModel>
</configuration>

そして、エントリーポイントに以下のコードを追加する。

WcfService/Program.vb
Module Program
    Sub Main()
        Dim svcHost As ServiceHost = New ServiceHost(GetType(WcfServiceImpl))
        svcHost.Open()

        Console.ReadKey()
    End Sub
End Module

これでアプリケーションを起動すれば、サービスが公開される。

Client側の実装

あとはこのサービスを利用するクライアントを定義するだけ。

まずはアプリケーション構成ファイルにendpointを定義する。

App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <client>
            <endpoint
                name="wcfService"
                address="net.tcp://localhost:8081/wcfService"
                contract="WcfServiceInterface.IWcfService"
                binding="netTcpBinding" />
        </client>
    </system.serviceModel>
</configuration>

あとはエントリーポイントでサービスに接続するコードを書くだけ。

WcfClient/Program.vb
Module Program
    Sub Main()
        Dim factory = New ChannelFactory(Of IWcfService)("wcfService")
        Dim wcfService = factory.CreateChannel()
        Dim customer = wcfService.GetCustomer()

        Console.WriteLine("Name = {0}", customer.Name)
        Console.ReadKey()
    End Sub
End Module

これだけでServer側でオブジェクトをアクティブ化して、クライアント側からプロキシ経由でオブジェクトのメソッドを呼び出す事ができる。.NET Remotingと比べるとMarshalByRefObjectSerializable属性を使わなくても済むので、若干楽になった印象。

後は拡張性とかかすごいんでしょうね。まだ全然さわってないからわかんないけど。

まだ、CAOとSAOとかSingletonとSingleCallとかがどうなっているのか知らないので、その辺を調べていこうかと思う。

あ〜、VBつまんねぇ。

*1:そろそろ.netに戻れそう