Поделиться через


Контейнеры, веб-узлы и компоненты

Контейнер — это специализированная коллекция, являющаяся "логическим" хранилищем одного или нескольких компонентов. Контейнеры управляют взаимодействием компонентов друг с другом и с внешней средой приложения, предоставляя реализацию интерфейса ISite, через который могут осуществляться эти взаимодействия. С помощью контейнеров можно отслеживать компоненты по принципу "первым поступил — первым обслужен" (first-in, first-out, FIFO) и обращаться к компонентам по индексу. Контейнеры также предоставляют средства для удаления компонентов, которые больше не нужны.

Контейнер — это не визуальное или физическое, а логическое хранилище компонентов. Контейнер инкапсулирует один или несколько компонентов и предоставляет оболочку, через которую могут взаимодействовать клиенты. Для добавления и удаления элементов в контейнере используется следующий синтаксис:

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 можно получить доступ к самым разнообразным службам. Эти службы обеспечивают расширенную поддержку интеграции компонентов в среду разработки. Дополнительные сведения см. в разделах Практическое руководство. Обращение к службам времени разработки и Архитектура времени разработки.

См. также

Задачи

Практическое руководство. Создание контейнеров компонентов

Практическое руководство. Усовершенствование контейнеров компонентов

Практическое руководство. Обращение к службам времени разработки

Основные понятия

Связь между контейнерами и компонентами

Архитектура времени разработки