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