Реалізація подій COM + в середовищі Delphi 5, Delphi, Програмування, статті

Автор: Андрій Семак, Королівство 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>

*

*