コンテナー、Site、およびコンポーネント
コンテナーは、コンポーネントに対して論理的なコンテインメントを提供する特別なコレクション オブジェクトです。 コンテナーは、やり取りを媒介するための ISite インターフェイスの実装によって、コンポーネント間および外部アプリケーション環境とのやり取りを管理します。 コンテナーを使用することにより、コンポーネントを先入れ先出し方式で追跡でき、また、コンポーネントをインデックスで参照できます。 また、コンテナーによって、不要になったコンポーネントを破棄するための共通手段も提供されます。
コンテインメントとは論理的なコンテインメントを意味し、ビジュアルな、または物理的なコンテインメントを意味するのではありません。 コンテナーはコンポーネントをカプセル化し、クライアントがコンポーネントとやり取りするためのラッパーとして機能します。 コンテナーでは、次の構文を使用してコンポーネントを追加、削除できます。
Imports System.ComponentModel
Dim myComponent As New Component()
Dim myContainer As New Container()
myContainer.Add(myComponent)
myContainer.Remove(myComponent)
using System.ComponentModel;
Component myComponent = new Component();
Container myContainer = new Container();
myContainer.Add(myComponent);
myContainer.Remove(myComponent);
コンポーネント コンテナーは、Container クラスのインスタンスか、IContainer インターフェイスの実装のどちらかになります。 Container は、このインターフェイスの参照の実装です。
コンポーネント名の指定
コンテナー内でコンポーネントの名前も指定できます。 この名前はコンテナー内で固有である必要があります。コンポーネントの名前は Add メソッドで指定します。
Dim myComponent As New Component()
Dim myContainer As New Container()
MyContainer.Add(myComponent, "ThisComponent")
Component myComponent = new Component();
Container myContainer = new Container();
myContainer.Add(myComponent, "ThisComponent");
リソースの管理とコンテナーの拡張
コンテナーを使用することで、コンポーネントに関連付けられたリソースを集中管理できます。 Dispose メソッドが呼び出されると、コンテナーは含んでいるすべてのコンポーネントの Dispose メソッドを自動的に呼び出すため、リソースが迅速に解放されます。
コンテナーは拡張できます。 Container を継承してカスタム機能を持つ独自のクラスを作成できます。 たとえば、次の例に示すように、追加できるコンポーネントを管理するための規則を適用するコンテナーを作成できます。
Public Class MyContainer
Inherits Container
Public Overloads Overrides Sub Add(ByVal component As IComponent)
' Checks to see if the component is allowed to join this container.
If TypeOf component Is Widget Then
' Calls the Add method of the base class, and adds the component.
MyBase.Add(component)
Else
' If the component is not allowed, an exception is thrown.
Throw New NonWidgetException()
End If
End Sub
End Class
class MyContainer : Container
{
public override void Add(IComponent component)
{
// Checks to see if the component is allowed to join this container.
if (component is Widget)
{
base.Add(component);
}
else
{
throw new NonWidgetException();
}
}
}
上の例では、コンテナーに含めることができるコンポーネントに関する規則を適用するための新しいコンポーネント クラスを作成しています。 コンポーネントが指定されたクラス (この場合は Widget) に属していない場合は、例外がスローされます。
コンポーネントがコンテナーに追加されると、コンテナーはそのコンポーネントに対するサイトを作成します。 これは、コンポーネントの Site プロパティを介して公開される ISite インターフェイスの実装です。 コンポーネントは、Site プロパティによってそのホスト コンテナーとやり取りします。 このプロパティは、コンポーネントの論理的な場所を表し、コンテナーによってホストされます。 コンテナーに含まれていないコンポーネントは、Site プロパティに対して null 参照を返します。 Site プロパティによって、コンテナー インターフェイスへの参照を ISite.Container プロパティを介して取得したり、ホストされているコンポーネント インターフェイスへの参照を Component プロパティを介して取得したりできます。
Dim myComponent As New Component
Dim myContainer As New Container
myContainer.Add(myComponent)
Dim myIComponent as IComponent
Dim myIContainer as IContainer
myIComponent = myComponent.Site.Component
myIContainer = myComponent.Site.Container
' These two messages display True.
MessageBox.Show("Are the components equal? " & _
myComponent.Equals(myIComponent).ToString)
MessageBox.Show("Are the containers equal? " & _
myContainer.Equals(myIContainer).ToString)
Component myComponent = new Component();
Container myContainer = new Container();
myContainer.Add(myComponent);
IComponent myIComponent;
IContainer myIContainer;
myIComponent = myComponent.Site.Component;
myIContainer = myComponent.Site.Container;
MessageBox.Show("Are the components equal? " +
myComponent.Equals(myIComponent).ToString());
MessageBox.Show("Are the containers equal? " +
myContainer.Equals(myIContainer).ToString());
これらのプロパティはいずれも、オブジェクトに関連付けられたインターフェイスだけを返し、オブジェクト自体への参照は返しません。 コンポーネントには、Container と同じインターフェイスを返す Container プロパティもあります。 このプロパティはサイトを介して提供され、ショートカットとして考えることができます。
Add メソッドを使用してコンポーネントに名前を付けた場合は、Name プロパティを使用して名前を取得できます。 コンテナーにサービス オブジェクトが関連付けられている場合、コンポーネントは GetService メソッドによってそのオブジェクトへの参照を取得できます。
サービスへのアクセス
GetService メソッドによってさまざまなサービスにアクセスできます。 これらのサービスには、コンポーネントをデザイン環境に統合するための広範なサポートが用意されています。 詳細については、「方法 : デザイン時サービスにアクセスする」および「デザイン時アーキテクチャ」を参照してください。