Реалізація подій COM + в середовищі Delphi 5

Автор: Андрій Семак, Королівство Delphi


Введення


Обробка подій є одним з ключових моментів в COM. Існує маса програм, для нормального функціонування яких потрібно підтримка подій.

GUI користувача повинен вміти обробляти різну кількість подій, наприклад, таких як: натискання на кнопку миші, переміщення миші по екрану і т.д. Приблизно так само може виникнути потреба обробляти події всередині об'єктів COM. У даній статті ми розглянемо принцип роботи вільно пов'язаних подій і створимо наочне додаток для демонстрації їх використання такого типу подій в COM +. (Для більш детальної інформації про події в COM + дивіться статтю А. Новика "Система підтримки подій COM +" на сайті журналу "Клієнт-Сервер").




Що таке вільно зв'язані події? Поняття "Видавець-Передплатник"

До появи COM +, модель COM підтримувала систему подій, реалізовану через інтерфейс IConnectionPointContainer. Це жорстко пов'язані події. (У даній статті, ми не будемо розглядати реалізацію цього підходу). В COM + з'явилося нове поняття: ВІЛЬНО ПОВ'ЯЗАНІ ПОДІЇ (Loosely coupled events – LCE), розроблені для задоволення потреб розподілених обчислень.


В COM + Ініціатор події (Видавець) і споживач (Передплатник) вільно пов'язані.

Інформація від різних видавців зберігається в каталозі COM +, а передплатники вказують, яку інформацію вони хочуть отримувати, реєструючись в каталозі.




Архітектура подій в COM +

Для реалізації вільно пов'язаних подій ви повинні створити компонент EventClass, який буде зареєстрований в каталозі COM +. Передплатники викликаються об'єктом події, який визначає і активізує об'єкти, підписані на нього.


Слід розрізняти види передплати. Існує тимчасова і постійна передплати.
Тимчасова передплата (transient) створюється засобами адміністративного API. Для більш детальної інформації можна звернутися в MSDN. Керувати життєвим циклом такий підписки потрібно програмними засобами. А не засобами ComponentServices.
Постійна передплата (persistent) створюється засобами ComponentServices. Така підписка в змозі пережити перезапуск системи.

Фільтрація існує тільки в системі COM +. Такої можливості немає в системі жорстко пов'язаних подій. Її суть ми розглянемо далі, при більш детальному вивченні прикладу.




Приклад реалізації компоненту EventClass

Припустимо, в нас існує завдання на базі існуючої системи, що функціонує в середовищі COM +, реалізувати систему ведення власне журналу подій в текстовому файлі. Для початку нам потрібно реалізувати компонент EventClass, про який йшлося вище. Він буде представляти собою порожню заглушку для передплатника. Саме через нього будуть запускатися наші передплатники у каталозі COM +.


Коли компонент-видавець буде створювати подія, компонент EventClass передасть всі вхідні параметри події і активізує всіх передплатників.


Важливо!
Метод події може містити тільки вхідні параметри [in]. Вихідним може бути тільки результуючий тип HRESULT, прийнятий в COM для визначення статусу завершення S_OK, в результаті успіху або E_FAIL, в результаті невдачі виконання методу.

Запустимо середу Delphi, створимо просту ActiveX бібліотеку і помістимо в неї об'єкт автоматизації (Automation Object). Визначимо нумератор типів помилок і створимо інтерфейс ISysLogEvent з методом ReportLog.
type

LogMessageTypes = TOleEnum;

const
lmtInformation = $00000000;
lmtWarning = $00000001;
lmtError = $00000002;
lmtFatal = $00000003;
lmtDebug = $00000004;
lmtUnknown = $00000005;

type
TSysLogEvent = class(TAutoObject, ISysLogEvent)
protected
procedure ReportLog (enMsgType: LogMessageTypes; const strUserName,
strModuleName, strMsgText: WideString); safecall;
{ Protected declarations }
end;

Бібліотека типів зображена на рис. 1.

У розділі Implementation створимо заглушку методу для EventClass:
implementation

uses ComServ;

procedure TSysLogEvent.ReportLog(enMsgType: LogMessageTypes;
const strUserName, strModuleName, strMsgText: WideString);
begin

// Event class methods are not implemented.

end;

initialization

TAutoObjectFactory.Create (ComServer, TSysLogEvent, Class_SysLogEvent,
ciMultiInstance, tmApartment);

end.


На цьому закінчимо. Залишається зареєструвати заглушку в нашому застосуванні COM +. Якщо програма не створено, створіть його через засоби ComponentServices.
Вікно реєстрація компонента EventClass зображено на рис.2.


 




Приклад реалізації Об'єкту-передплатника

Після реєстрації компонента EventClass створимо компонент-передплатник.
Точно так само, як при створенні компонента EventClass створимо бібліотеку і об'єкт автоматизації. Трохи буде відрізнятися наповнення реалізації методів і метод реєстрації.
Створимо інтерфейс з методом, аналогічним методу інтерфейсу ILogEvent – ISysLog (Мал. 3):


Важливо!
Не забудьте підключити до вашої бібліотеки типів зареєстровану в ComponentServices бібліотеку з заглушкою EventClass і вкажіть інтерфейс ISysLogEvent в розділі Implements як показано на рис. 3а.


Нижче приведений код компоненти передплатника, який буде отримувати події від видавця. З реалізації бізнес-логіки видно, що при виникненні методу-події ReportLog, компонент-передплатник буде видавати діалогове вікно з інформацією для запису в журнал. Якщо ви заміните реалізацію цього методу програмним кодом запису у файл, ви отримаєте готовий компонент для реєстрації ваших подій у бізнес об'єкті (Виведення інформації, повідомлень про помилки, налагодженні і т.д.).

unit SysLogUnit;
interface
uses

ComObj, ActiveX, SystemLogger_TLB, StdVcl, LogEvent_TLB, Dialogs;
type

TSysLog = class(TAutoObject, ISysLog, ISysLogEvent)
protected
procedure ReportLog (enMsgType: LogMessageTypes; const strUserName,
strModuleName, strMsgText: WideString); safecall;
{ Protected declarations }

end;

implementation

uses ComServ, SysUtils;

procedure TSysLog.ReportLog (enMsgType: LogMessageTypes; const strUserName,
strModuleName, strMsgText: WideString);
begin
ShowMessage(“MessageType : “+IntToStr(enMsgtype)+#10#13+
“ModuleName : “+strModuleName+#10#13+
“UserName : “+strUserName+#10#13+
“TextMessage : “+strMsgText);
end;

initialization
TAutoObjectFactory.Create(ComServer, TSysLog, Class_SysLog,
ciMultiInstance, tmApartment);
end.

Зареєструйте компонент в каталозі COM + і підпишіть його до компоненту EventClass. Як це зробити? Дивіться рис. 4.


Рис. 4
Дотримуйтесь інструкції візарду і зробіть вибір як показано на рис.5


Рис. 5

Отже, у вас на комп'ютері встановлені об'єкти EventClass і передплатник.




Приклад реалізації методів видавця

Створимо простеньку додаток і перевіримо существующею зв'язку. Створіть бізнес-об'єкт COM + ініціює в будь-якому своєму методі метод-подія ReportLog.
Приклад реалізації об'єкта наведено нижче:

unit BsObjectUnit;
interface
uses

ComObj, ActiveX, BsObject_TLB, StdVcl, LogEvent_TLB;

type

TBusinessObject = class(TAutoObject, IBusinessObject)
protected
function NewObject(param1: Integer): HResult; safecall;
{ Protected declarations }
end;

implementation

uses ComServ;

function TBusinessObject.NewObject(param1: Integer): HResult;
var
LogEvent : ISysLogEvent;
begin
LogEvent := CoSysLogEvent.Create;
try
LogEvent.ReportLog (lmtInformation, "Nonamed", "BsObjectUnit", "TBusinessObject.NewObject executed!")
except
LogEvent.ReportLog (lmtInformation, "Nonamed", "BsObjectUnit", "TBusinessObject.NewObject failed!")
end;
end;

initialization
TAutoObjectFactory.Create (ComServer, TBusinessObject, Class_BusinessObject,
ciMultiInstance, tmApartment);

end.


Після виклику методу NewObject в об'єкта BusinessObject буде створено подію, яка створить об'єкт SysLog і запише і відобразить інформацію в діалоговому вікні. Підписчиків у створеного об'єкта EventClass може бути необмежена кількість з найрізноманітнішими функціями, від відображення діалогового вікна до запису даних в окрему БД.




ФІЛЬТРИ

Механізм фільтрації передплатників використовує рядок умови фільтрації, що є властивістю передплати. Така фільтрація виконується для кожного методу і кожної підписки. Ви можете використовувати рядок, використовуючи імена параметрів з бібліотеки типів. Можна використовувати також стандартні операції відносини, вкладені дужки і ключові слова AND, OR, NOT. Рядок може бути визначена за допомогою засобів ComponentServices або засобів адміністративного API.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*