拡張可能オブジェクト

拡張可能オブジェクト パターンは、既存のランタイム クラスに新しい機能を付加して拡張したり、オブジェクトに新しい状態を追加するために使用します。このようなオブジェクトを実際に拡張することにより、処理の段階に応じて、共通の拡張可能オブジェクトに定義された共有の状態や機能にアクセスすることができます。

IExtensibleObject<T> パターン

拡張可能オブジェクト パターンには、IExtensibleObjectIExtension、および IExtensionCollection の 3 つのインターフェイスがあります。

IExtensibleObject インターフェイスを実装することにより、IExtension オブジェクトの機能をカスタマイズできます。

拡張可能オブジェクトを使うと、IExtension オブジェクトの動的な集約が可能になります。IExtension オブジェクトには、次のインターフェイスが実装されています。

public interface IExtension<T>
where T : IExtensibleObject<T>
{
    void Attach(T owner);
    void Detach(T owner);
}

この型制約は、IExtensibleObject であるクラスに対してしか拡張を定義できないことを保証します。AttachDetach は、集約や集約解除に関する通知を提供します。

所有者が追加や削除を行う際の制限を組み込むことも可能です。たとえば、削除は全面的に禁止する、所有者や拡張がある状態であれば拡張の追加や削除を禁止する、同時に複数の所有者に追加することを禁止する、1 つ削除したら 1 つだけ追加を許可する、などの制約を指定することができます。

IExtension を実装しても、他の標準のマネージ インターフェイスとやりとりできるとは限りません。特に、所有者オブジェクトの System.IDisposable.Dispose メソッドは、自分自身の拡張を解除しないのが普通です。

拡張がコレクションに追加される場合には、直前に Attach が呼び出されます。また、コレクションから拡張を削除すると、その直後に Detach が呼び出されます。したがって、同期が適切であれば、拡張が有効なのは Attach から Detach の間ということになります。

FindAllFind に渡すオブジェクトは、IExtension である必要はなく、任意のオブジェクトを渡すことができますが、返される拡張は IExtension です。

コレクション内のどの拡張も IExtension でなければ、Find は null を返し、FindAll は空のコレクションを返します。IExtension を実装した拡張が複数あれば、Find はそのうちのいずれか 1 つを返します。FindAll から返される値はスナップショットです。

主な使い方として、次の 2 つのシナリオが考えられます。1 つ目のシナリオでは、型ベースのディクショナリとして Extensions プロパティを使用し、オブジェクトに状態を追加します。これは、別のコンポーネントが型に基づいて検索できます。

2 つ目のシナリオでは、Attach プロパティおよび Detach プロパティを使用し、イベントへの登録や、状態の遷移の監視など、カスタムの動作にオブジェクトを参加させます。

IExtensionCollection インターフェイスは、IExtension オブジェクトのコレクションであり、型を基準にした IExtension の検索を実現します。System.ServiceModel.IExtensionCollection.Find は、指定された型の IExtension オブジェクトのうち、最も新しく追加されたものを返します。

Windows Communication Foundation の拡張可能オブジェクト

Windows Communication Foundation (WCF) には次の 4 つの拡張可能オブジェクトが組み込まれています。

  • ServiceHostBase : サービス ホストの基本クラスです。ServiceHostBase 自身の動作を拡張するほか、各サービスの状態を保存しておくための拡張が可能です。
  • InstanceContext : サービスのランタイムを使用して、サービスの型のインスタンスと接続するためのクラスです。このクラスは、インスタンスに関する情報のほか、InstanceContext に含まれる ServiceHostBase への参照を保持します。InstanceContext 自身の動作を拡張するほか、各サービスの状態を保存しておくための拡張が可能です。
  • OperationContext : 操作ごとにランタイムが収集した操作情報を表すクラスです。具体的には、受け取ったメッセージのヘッダーやプロパティ、受け取ったセキュリティ ID などの情報があります。OperationContext 自身の動作を拡張するほか、各操作の状態を保存しておくための拡張が可能です。
  • IContextChannel : WCF ランタイムで構築されたチャネルやプロキシの状態を個々に検査できるようにするためのインターフェイスです。IClientChannel 自身の動作を拡張するほか、各チャネルの状態を保存しておくための拡張が可能です。

InstanceContext オブジェクトの状態を追跡するという、簡単な拡張の使い方を例示したコードを次に示します。

関連項目

リファレンス

IExtensibleObject
IExtension
IExtensionCollection