System.Runtime.Remoting.Contexts 名前空間

SDK ドキュメントでは、

TYPE 型は、.NET Framework インフラストラクチャのサポートを目的としています。独自に作成したコード内で直接使用することはできません。

という文章で何も情報がないが、Google などで検索すると、コンテキスト関係を利用する場合には、このあたりのクラス群を扱うことが、どうしても必要になるようだ。
public なクラスは、

  • Context
  • ContextAttribute
  • ContextProperty
  • SynchronizationAttribute

このうち SynchronizationAttribute に関しては、唯一 SDK によって解説されたクラスである。
public なインターフェスは、

  • IContextAttribute
  • IContextProperty
  • IContextPropertyActivator
  • IContributeClientContextSink
  • IContributeDynamicSink
  • IContributeEnvoySink
  • IContributeObjectSink
  • IContributeServerContextSink
  • IDynamicMessageSink
  • IDynamicProperty

最後に、public delegate として

  • CrossContextDelegate

といったところで、これらについて簡単に見ていこうかと思う。

SynchronizationAttribute クラス

最初に見るのは、きちんとドキュメントされている SynchronizationAttribute から。
クラス名でわかるように属性であり、その機能もかなりシンプルなものになっている。
前述の全文検索の結果から、この属性を付与することによって得られる効果は説明文から十分に予測できるが、実際に試してみるほうがよくわかる。

[Synchronization(false)]
public class Test1 : ContextBoundObject
{
  public void test(object info)
  {
    Trace.WriteLine("+ " + info);
    try
    {
      Thread.Sleep(1000);
    }
    finally
    {
      Trace.WriteLine("- " + info);
    }
  }
}

public class SyncTest
{
  static void Main()
  {
    Test1 t = new Test1();
    for (int n = 0; n < 10; n++)
    {
      ThreadPool.QueueUserWorkItem(new WaitCallback(t.test), n);
    }
    
    Console.ReadLine();
  }
}

最初の SynchronizationAttribute を付けはずししてみることで、その効果を確認することができるだろう。
この時点で、属性によってメソッドの挙動を変化させているということに驚くべきなのだが、あまりにも簡単に挙動を変化させられてしまうので、ちょっと簡単に驚けない。

ContextAttribute クラスと IContextAttribute インターフェス

次の切り口として扱いやすいのは、この SynchronizationAttribute の親である ContextAttribute クラスと、それに非常に似た名前の IContextAttribute インターフェスではないかと目星をつけてみた。
実際、ContextAttribute は IContextAttribute の標準的な実装を提供するヘルパークラスであるようなので、当面の目的の1つとして IContextAttribute を実装した属性の作成があげられるだろう。

ContextProperty クラスと IContextProperty インターフェス

もう少し注意深く ContextAttribute クラスを見ると、IContextProperty インターフェスの実装もかねていることがわかる。
ContextProperty と IContextProperty は、ContextAttribute と IContextAttribute のような関係ではないことも、public インターフェスを比べてみることでわかる。
ContextProperty クラスは string と object のペアを保持するだけの何の機能も持たないデータクラスであることもすぐにわかるが、IContextProperty インターフェスのメソッドがどのような機能をもつかは、簡単にわかるようなものではない。

IContributeClientContextSink と IContributeServerContextSink

SynchronizationAttribute は、ドキュメントにはない上記2つのインターフェスを実装している。
この2つのインターフェスは名前が異なるだけで、どちらも前述の IMessageSink を取り出すための実装を提供するためのメソッドを要求する。
このインターフェスは、これまでの内容に対して、求めていたものそのものに近いことが予測される。

IContributeDynamicSink, IContributeEnvoySink, IContributeObjectSink

これら、似た名前のインターフェス群も、同様に名前の違う...つまり役割が異なる IMessageSink を取得することを可能とするためのインターフェスであることが予測される。

IDynamicMessageSink

IContributeDynamicSink から返される。
IMessageSink とは異なるインターフェスを持つメッセージシンクだとうと予測されるが、とりあえず IDynamicProperty と共に、用途が見えてくるまでは考えないでおこう。

Context クラス

おそらくコンテキストそのもの。
非常に豊富なメソッドを持っているので、一通りメソッド名を眺めておく程度にとどめておこう。

IContextPropertyActivator インターフェス

いくつか興味ある名前のメソッドを定義しているので、多少気に留めておこうかという程度。
ContextProperty クラスが名前と値のペアであることを考えると、IContextProperty の メソッドと対応付けて考えるべきだろう。



一通りのインターフェスを見たところで、大体狙いどころとなる目星はついたので、そこらへんから切り崩していけるのではないだろうか。