Развертывание сборки, использующейся со службами COM+, будет ненамного труднее, чем развертывание любой другой сборки .NET.
Первое: необходимо предоставить сборке сильное имя. Это делается с помощью утилиты
sn.exe
из SDK .NET (см. главу 10).
sn.exe
будет выводить файл сильного имени, на который можно ссылаться из командной строки, когда сборка компилируется, чтобы встроить сильное имя в компилированную сборку.
Второе: необходимо зарегистрировать сборку в глобальном кэше сборок (см. главу 10).
Если сборку будут использовать только управляемые клиенты (то есть, клиенты .NET), никаких дополнительных усилий по развертыванию
не требуется. Когда управляемый клиент создает в сборке экземпляр обслуживаемого класса, CLR использует атрибуты в сборке для автоматической регистрации компонента в службах COM+.
Однако, если классы в сборке используются неуправляемым кодом, необходимо самостоятельно явно зарегистрировать сборку в службах COM+ до выполнения любой клиентской программы. Программа для выполнения этой регистрации,
RegSvcs.exe
, предоставляется компанией Microsoft как часть SDK .NET. Когда
RegSvcs
выполняется на компоненте .NET, она создает приложение COM+ с именем, указанным атрибутом
ApplicationName
в сборке, и импортирует сборку в него.
Для чего же требуется RegSvcs.exe?
Как можно помнить из предыдущей главы по взаимодействию COM, сборки .NET имеют архитектуру, отличную от архитектуры компонентов COM. Задача
RegSvcs.exe
состоит в разрешении этих различий, чтобы сборки .NET удовлетворяли интерфейсу, ожидаемому службами COM+. Чтобы выполнить свою работу, утилита
RegSvcs.exe
проделывает четыре вещи.
1. Загружает и регистрирует сборку .NET.
2. Создает библиотеку типов для сборки .NET.
3. Импортирует библиотеку типов в приложение служб COM+.
4. Использует метаданные внутри DLL, чтобы правильно сконфигурировать библиотеку типов внутри приложения служб COM+.
RegSvcs
не только заботится обо всех деталях импортирования сборки в службы COM+, но предоставляет также достаточно хороший контроль за тем, как это происходит. Этот контроль обеспечивается в форме дополнительных параметров командной строки. Вот синтаксис команды:
) можно определить другое имя для создаваемого приложения COM+, предоставляя второй аргумент командной строки при вызове
RegSvcs
. Для еще большей гибкости можно определить имя файла библиотеки типов, которая создается при предоставлении третьего аргумента (
TypeLibrary.tlb
). Желательно всегда предоставлять эти аргументы при вызове
RegSvcs
, так как более ранние версии этой программы будут молчаливо перезаписывать любые существующие файлы, которые могут иметь такие же имена, как у вновь создаваемых файлов.
Предварительные итоги
Теперь мы знаем, как подготовить сборку .NET для применения вместе со службами COM+. Эта подготовка включает в себя:
□ Соединение классов прокси с внутренними "рабочими" классами посредством атрибута
ComEmulate
□ Развертывание сборок с помощью
sn.exe
,
al.exe
и, возможно,
RegSvcs.exe
Имея общую информацию, перейдем к обсуждению использования конкретных служб COM+ из сборок .NET. Начнем с транзакций.
Использование транзакций со сборками .NET
Существуют две вещи, которые необходимо сделать, чтобы подготовить класс .NET для транзакций. Первое: необходимо изменить прокси класса с помощью
атрибута для указания его уровня поддержки транзакций. Второе: необходимо добавить в класс код для управления его поведением, когда он участвует в транзакциях.
Вспомним концепцию "контекста" транзакции, которая была рассмотрена выше. Она играет здесь важную роль, поэтому к ней можно вернуться для быстрого повторения.
Определение транзакционной поддержки
Ранее при использовании транзакций из служб COM+ можно было увидеть настройку уровня транзакций в окне свойств класса в Snap-In службы компонентов. Эта настройка позволяет задать уровень поддержки транзакций, который службы COM+ будут предоставлять стандартному компоненту COM.
Иначе в .NET уровень поддержки транзакций в сборке можно определить не с помощью графического окна в snap-in службы компонентов, а программным путем с помощью атрибута
Transaction
, определенного в пространстве имен
EnterpriseServices
. В примере ниже мы определяем, что следующий класс прокси должен поддерживать транзакции. При заданном значении атрибута компонент будет сконфигурирован для поддержки транзакций, когда он импортируется в службы COM+ с помощью
RegSvcs.exe
.
[Transaction(TransactionOption.Supported)]
public class ProxyClass:ServicedComponent {
}
Supported
является только одним из нескольких значений, которые можно присвоить атрибуту
Transaction
компонента. Фактически, существует четыре значения, которые представлены в перечислении
TransactionOption
, являющемся частью пространства имен
System.EnterpriseServices
.
□ Когда атрибут
Transaction
класса задан как
Disabled
, службы COM+ не предоставляют транзакционной поддержки для класса, даже если такая поддержка определена где-то в коде. (Другими словами, вызовы этого класса, сделанные для
ContextUtil
с целью фиксации или отмены транзакций, игнорируются. Мы познакомимся с
ContextUtil
в следующем разделе.)
□ Когда атрибут
Transaction
класса задан как
NotSupported
, такой класс не вовлекается в транзакции, запускаемые его клиентами, другими словами он не помещается в их контекст. В данной конфигурации объекты этого класса не определяют, будет ли вызываемая транзакция фиксироваться или отменяться.
□ Когда атрибут
Transaction
класса задан как
Supported
, объекты этого класса могут вовлекаться в контекст транзакций своих вызывающих клиентов, если эти вызывающие клиенты на самом деле начинают транзакцию. Такой объект не может самостоятельно порождать транзакцию.
□ Когда атрибут
Transaction
класса задан как
Required
, службы COM+ знают, что объекты этого класса могут выполняться только в контексте транзакции. Если такой объект вызывается клиентом, имеющем транзакционный контекст, объект наследует контекст транзакции клиента. Если, однако, объект вызывается клиентом, который не имеет транзакционного контекста, службы COM+ создают контекст для этого объекта.
□ Когда атрибут
Transaction
класса задан как
RequiresNew
, службы COM+ создают новую транзакцию для класса каждый раз, когда он вызывается. Даже если клиент объекта уже имеет транзакцию, службы COM+ создают новую транзакцию для серверного объекта. Как можно догадаться, классы, сконфигурированные подобным образом, способны отменить только свои собственные транзакции, а не работу своих клиентов.