Опубликован: 11.05.2007 | Доступ: свободный | Студентов: 1698 / 235 | Оценка: 4.36 / 4.25 | Длительность: 16:06:00
Лекция 7:

Промежуточная среда COM+ и служба Enterprise Services

Создание обслуживаемых компонент

Обслуживаемая компонента .NET Framework является объектом класса, наследованным от System.EnterpriseServices.ServicedComponent, и отвечающим следующим требованиям:

  • класс имеет спецификатор public ;
  • класс содержит публичный конструктором без параметров;
  • класс не является абстрактными, статическим, или классом общего вида.

Статические методы в классе компоненты возможны, но они выполняются в контексте клиента, и имеют доступа к контексту COM+ клиента, если таковой существует.

Класс сервисной компоненты должен быть объявлен в сборке, которая может быть зарегистрирована в качестве приложения COM+. Такая сборка не должна иметь классов общего вида со спецификатором public, и должна быть подписана.

Класс обслуживаемой компоненты может иметь атрибуты из пространства имен System.EnterpriseServices, связанные с транзакцией ( TransactionAttribute ), активацией ( JustInTimeActivationAttribute и ObjectPoolingAttribute ) и синхронизацией ( SynchronizationAttribute ). Как упоминалось ранее, поддержка транзакции автоматически означает JIT-активацию и участие в активности, тем не менее следует перечислять атрибут JIT активации явно.

Рассмотрим код простейшей обслуживаемой компоненты.

// Файл SampleComponent.cs
using System;
using System.EnterpriseServices;

[assembly: ApplicationAccessControl(false)]
[assembly: ApplicationName("Serviced Component Example 01")]
[assembly: Description("Sample of .NET serviced component.")]
[assembly: ApplicationActivation(ActivationOption.Server)]

Эти атрибуты задают свойства сборки, которая затем будет зарегистрирована в качестве приложения COM+. Атрибут ApplicationActivation позволяет выбрать серверный или библиотечный тип приложения.

namespace ServicedComponentSample
{
    [JustInTimeActivation]
    [Transaction(TransactionOption.Required)]
    [ObjectPooling(Enabled=true, MinPoolSize=5, MaxPoolSize=10)]
    public class SampleComponent: ServicedComponent
    {

Объявленный выше класс компоненты, как видно из атрибутов, требует наличия транзакции и использует JIT активацию с пулом объектов

public SampleComponent()
{
}

Для использования в пуле объект должен быть возвращен в свое первоначальное состояние (деактивизирован). Для поддержки режима активации одного вызова компонента не должна иметь состояния, сохраняемого между вызовами ее методов клиентом, и таким образом часто она не требует каких-либо действий для перевода в первоначальное состояние. При необходимости можно перекрыть виртуальные методы Activate и Deactivate, вызываемые при операциях активации и деактивации, и производить в них сброс состояния объекта.

protected override void Activate()
{
}

protected override void Deactivate()
{
   // Здесь при необходимости можно очистить 
   // состояние объекта и освободить ресурсы 
}

Метод CanBePooled возвращает true, если объект может быть возвращен в пул объектов после деактивации, иначе он уничтожается.

protected override bool CanBePooled()
{
    // Подтверждает возможность помещения объекта в пул
    return true;
}

Атрибут System.EnterpriseServices.AutoCompleteAttribute применяется для автоматического участия методов в транзакции. Если метод завершается нормально, то считается, что он подтвердил успешное завершение транзакции, при возникновении же в методе не пойманного исключения транзакция будет отменена.

[AutoComplete]
public void Do()
{
}

    }
}
// Файл SampleComponent.cs

Альтернативный AutoComplete вариант использования транзакций заключается в вызове статических методов класса ContextUtil. Этот класс используется для доступа и изменения контекста COM+, связанного с обслуживаемой компонентой. Метод ContextUtil.SetComplete сообщает COM+ об успешном завершении метода, а ContextUtil.SetAbort предопределяет отмену транзакции. Используются они обычно следующим образом.

try
{
    ...
    ContextUtil.SetComplete();
}
catch()
{
    ContextUtil.SetAbort();
}

Постоянное использование методов ContextUtil приводит к коду, который будет сложно перенести из компоненты COM+ в класс, выполняемый вне промежуточной среды COM+. Для решения этой проблемы следует либо использовать методы класса, оборачивающего методы ContextUtil, либо, в крайнем случае, атрибут AutoComplete, который игнорируется для обычных классов.