わんくま勉強会#6のかるぼさんのセッションにインスパイアされて調べました。キッカケはかるぼさんがCountUpというWebMethod(WCFではOperationContract)を作った時、フィールドに値を保持しようとしていたことです。(ちなみに、下記の内容はほとんどセッション後に話してたものだったりしますw)
まず、WCFのインスタンスのライフサイクルを説明する前に、WCFが登場する以前の.NET RemotingだったりWebサービス(asmx)のインスタンスのライフサイクルをおさらいしたいと思います。
といったところで、いくつもあるわけではないのでサクっと行きます。
1.要求ごとにインスタンスを生成する。
WebサービスやASP.NETがこのタイプです。.NET Remoting も設定でこのタイプを指定することができます。
2.インスタンスを一つだけ生成する。(Singleton)
.NET Remotingは設定でこのタイプを指定することができます。
この二つのパターンがあります。
では、WCFではどうなったかというと、上記の二つに加え、セッションごとにインスタンスを生成するというものが増えています。つまり、
3.セッションごとにインスタンスを生成する。
というのが3つ目の選択肢がWCFで新たに追加されています。簡単に言ってしまえば、クライアントごとにインスタンスを生成するというもので、ステートフルなサービスを作ることができます。ASP.NETのセッションと同じですね。設定方法は以下の通り
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
public class MyService : IMyService
IMyServiceはServiceContract、つまりサービスとして公開するインターフェースです。MyServiceはその実装で、その実装クラスにServiceBehaviorAttributeを付け、InstanceContextMode=InstanceContextMode.PerSessionを設定します。InstanceContextModeの列挙体は上記の説明からわかるように三つの値があります。
InstanceContextMode.PerCall
InstanceContextMode.Singleton
InstanceContextMode.PerSession
ところで、PerSessionでセッションごとにインスタンスを生成できるのはいいんだけど、サーバをクラスタ化している場合どうするんだろうか…ASP.NETみたいにDBに状態を保持させたりなんてできるのかな…それともロードバランサー側でクライアントのセッションが繋がるように割り振れということなのだろうか…というか、やっぱり分散系のベストプラクティスにあるようにステートレスな設計しなさいってことかな(´・ω・`)ショボーン
orz