容器、站点和组件

容器是一个专用集合对象,为一个或多个组件提供逻辑包容。 容器通过提供使交互得以发生的 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();
      }
   }
}
class MyContainer extends Container
{
   public void Add(IComponent component) throws NonWidgetException
   {
      // Checks to see if the component is allowed to join this container.
      if (component instanceof Widget) 
      {
         super.Add(component);
      }
      else
      {
         throw new NonWidgetException() ;
      }
   }
}   

上面的示例创建一个新的容器类,该类可以强制关于哪些组件能够联接该容器的规则。 如果组件不属于专用类(在本例中是 Widget),则将发生异常。

当组件添加到容器时,容器将为其创建一个站点。 这是 ISite 接口的一个实现,该接口通过组件的 Site 属性公开。 组件与其宿主容器的通信通过组件的 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());
Component myComponent =  new Component();
Container myContainer =  new Container();
myContainer.Add(myComponent);
IComponent myIComponent;
IContainer myIContainer;
myIComponent = myComponent.get_Site().get_Component();
myIContainer = myComponent.get_Site().get_Container();
MessageBox.Show("Are the components equal? " 
   + System.Convert.ToString(myComponent.Equals(myIComponent)));
MessageBox.Show("Are the containers equal? " 
   + System.Convert.ToString(myContainer.Equals(myIContainer)));

这两个属性都只返回与这些对象关联的接口,不返回对这些对象本身的引用。 请注意,该组件还有 Container 属性,该属性返回与 Container 相同的接口。 此属性通过站点提供,并且可以被视为快捷方式。

如果使用 Add 方法为组件分配名称,则通过 Name 属性可检索该名称。 如果容器有关联的服务对象,则组件可以通过 GetService 方法获取对该对象的引用。

访问服务

可以通过 GetService 方法访问各种服务。 这些服务为将组件集成到设计环境提供了广泛的支持。 有关更多信息,请参见 如何:访问设计时服务设计时体系结构

请参见

任务

如何:创建组件容器

如何:扩展组件容器

如何:访问设计时服务

概念

容器和组件之间的通信

设计时体系结构